yamlscript

Ingy döt Net 2025-01-17T23:54:40.792049Z

I wrote my first defmulti code today (first time for everything) https://github.com/yaml/yamlscript/commit/32a04fc2e1c10fcc8fcd5bba4139a5923f4b2991 I'd love a review if anyone wants to take a look..

2025-01-18T00:16:57.670999Z

Multimethods are super! (especially for open extension where speed isn't a huge distraction) The other day, the news of + "adding" functions made me howl with laughter! It brought to mind the Perl mantra TMTOWTDI. Scala too has a + operator (method) that works almost every-which-way on a variety of combinations of types. I learned about it from the book "Scala for the impatient", which is a hilarious book. But maybe there is a better way than the combinatorial unrolling of [nil Object], [Object nil], etc., etc. By the way, why isn't nil like 0 so nil+anything is the other thing?

Ingy döt Net 2025-01-18T00:22:53.129309Z

> By the way, why isn't nil like 0 so nil+anything is the other thing? Glad you asked. I really want it. It would make for cleaner idioms. I was afraid it might cause hard to find bugs. So I was limiting nil punning to collections. Do you have a good feel for what is best?

Ingy döt Net 2025-01-18T03:58:39.805989Z

> $ yamllm > (Use ctl-d or 'exit' to quit) > Q: What programming languages use nil punning with math operator functions?' > claude-3-5-sonnet-latest: > Common Lisp is a notable example of a programming language that uses nil punning > with math operators. In Common Lisp, nil is treated as both false and as an > empty list (), and it can be used in arithmetic operations where it's typically > treated as 0. > > Clojure, being a Lisp dialect, also has some nil punning behaviors, though it > handles them differently than Common Lisp. > > However, nil punning with math operators is not a common feature in most modern > programming languages, as it can lead to subtle bugs and make code harder to > reason about. Most languages today prefer explicit handling of null/nil values, > often through mechanisms like optional types or explicit null checks. > > Would you like me to explain more about how nil punning works in any specific > language?

Ingy döt Net 2025-01-18T04:00:08.749229Z

Seems to back up my apprehension.

Ingy döt Net 2025-01-18T04:05:47.446979Z

Also this seems to be in line with Clojure's handling of nil values, no?

2025-01-18T11:57:59.285099Z

In math, Perl apparently nil-puns to zero: e.g., perl -e 'print 3+$a;'. Some of the fresh air Yamlscript brings to this forum reminds me of Perl, so I was just curious. Thank you.

Ingy döt Net 2025-01-18T14:14:17.173139Z

fwiw, there's a reason I wanted infix comp and partial operations in YS. If you have a big existing YAML data file and want to insert a function, normally you would want to indent the tree that you are calling on, possibly causing a major undesired diff. Say this is somewhere in the middle of a 1000+ line yaml file:

foo:
  bar:
  - list
  - of
  - things
and you want to add 3 random words to the end of that list. You'd need to do:
foo:
  bar::
    concat _ slurp('/usr/share/dict/words'):lines:shuffle.take(3):
    - list
    - of
    - things    
But YS has tagged fns so you can do things like:
foo:
  bar: !:reverse
  - list
  - of
  - things
and even chained:
foo:
  bar: !:reverse:rest
  - list
  - of
  - things
but (on purpose) this tag syntax doesn't try to get fancy and allow extra args to fns. however you can compose partials where you need them:
foo:
  ws =: slurp('/usr/share/dict/words'):lines:shuffle.take(3)
  f1 =: \(shuffle ws) + (take + 3) + concat:flip
  bar: !:f1
  - list
  - of
  - things
That's the same as:
f1 =: comp(concat:flip partial(take 3) \(shuffle ws))
but I thought the + was a way to do it a bit cleaner.

Ingy döt Net 2025-01-18T14:14:51.692639Z

That's maybe a bit contrived and untested 🙂 Let me try it...

Ingy döt Net 2025-01-18T14:29:15.094979Z

Also NodeJS and PHP does same as Perl:

$ node -e 'console.log(42 + null)'
42
$ php -r 'print (42 + NULL) . PHP_EOL;'
42
$ perl -E 'say(42 + undef)'
42
But not most others:
$ clj -M -e '(+ 42 nil)'
Execution error (NullPointerException) at user/eval1 (REPL:1).
Cannot invoke "Object.getClass()" because "x" is null

Full report at:
/tmp/clojure-991860921987767293.edn
$ ruby -e 'puts(42 + $x)'
-e:1:in `+': nil can't be coerced into Integer (TypeError)

puts(42 + $x)
          ^^
	from -e:1:in `
' $ python -c 'print(42 + None)' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'

Ingy döt Net 2025-01-18T14:49:45.476859Z

wrt comp and partial idea above, here's a simpler example that I got working:

$ cat a.ys 
!yamlscript/v0:

foo:
  f1 =: shuffle + (take + 3)
  bar: !:f1
  - a
  - b
  - c
  - d
  - e

$ ys -Y a.ys 
foo:
  bar:
  - b
  - a
  - e

Ingy döt Net 2025-01-18T15:17:10.546349Z

Now I'm wanting to add namespaces 😄