5 ms·
This took me a minute to get, even after looking at the page about if: https://ryelang.org/meet_rye/basics/if_either/ https://ryelang.org/meet_rye/basics/if_ei
by justinpombrio 3y ago
This took me a minute to get, even after looking at the page about if:
https://ryelang.org/meet_rye/basics/if_either/ https://ryelang.org/meet_rye/basics/if_either/
The tricky thing about if, and, and or --- the reason you can't implement them as functions in most languages --- is that they need to not evaluate all their arguments immediately. Otherwise:
// Would print!
if(false, print("oops!"))
// Would throw an error if the key is not present
and(my_hashmap.has_key("key"), my_hashmap["key"])
The way that ryelang gets around this is that you pass the arguments in a "code block" surrounded by "{}", which delays its evaluation. So you write:
// Does not print, because *if* never runs its code block arg
if 0 { print("oops!") }
// There's no example of *and* anywhere but my guess is you'd write this:
and { my_hashmap.has_key("key") } { my_hashmap["key"] }
- nerdponx 3y agoThe R language has this feature as well. It's a whole lot of fun to work with.
- dmux 3y agoLikewise in Tcl where blocks can either be sent quoted (using {}) or unquoted (using “”). In the latter, variables and procs will have a round of substitution performed before being passed to the proc.
- middayc 3y agoRebol (where Rye took this from) is many times associated with Tcl. I've heard good things about it, but haven't really tried it yet.
- spindle 3y agoTCL is kinda similar to Rebol in some ways but in other ways it's the opposite of Rebol, because in TCL everything is a string (although it can ALSO have another type, thanks to clever shenanigans). (You probably knew this!)
- middayc 3y agoI heard this "everything is a string" line many times abot Tcl and it sounded a little unusual, but I havent delved deep enogh in tcl to see what it really meant and brought. I will.
- bch 3y agoeverything has a string rep available. It used to be that every thing was also represented literally by a string. So, for pedagogical purposes, a value 1 would be "1", and to do math, Tcl would do a strtol(val_storage), with the obvious performance implications. The way things are done now (and have been for a long time), is that values are stored in a struct Tcl_Obj{ int refCount; // objs can be shared int myType; // indicates whether currently a long, double, etc long longVal; double dblVal; [...] char *stringRep; int len; } ...in fact, the Tcl_Obj is more sophisticated than this, but for demonstration purposes this is fine. So "native" (eg: longVal) values are used when appropriate, no marshalling back/forth between strings, but the string rep is always available (can be generated), because that's what Tcl promises: everything is representable as a string. This is what brings the homoiconicity to Tcl - logically it's just passing text tokens around, and emitting text tokens. Internally, again, more sophisticated, but you get the point.
- keybored 3y agoThis is a very natural technique in concatenative languages.
- zelphirkalt 3y agoAs done in Smalltalk.
- nine_k 3y agoSmalltalk may be influential, but is now rarely used. The code block approach is widely applied in two massively used industrial languages though: Ruby and Kotlin. In Kotlin specifically it's one of the very central features.
- zelphirkalt 3y agoAnd Ruby has been strongly influenced by Smalltalk. Anyway, if you want something perhaps a bit more used, you can check out Pharo. I think that is the most used Smalltalk-like language these days.
- gumby 3y ago> The way that ryelang gets around this is that you pass the arguments in a "code block" surrounded by "{}" Like Lisp’s QUOTE which has to be a special form.
- seanhunter 3y agoIn the maxima computer algebra system[1] which was ancestrally based on lisp it has a single quote operator[2] which delays evaluation of something and a "double quote" (which acually two single quotes rather than an actual double quote) operator[3] which asks maxima to evaluate some expression immediately rather than leaving it in symbolic form.[4] [1] https://maxima.sourceforge.io/ https://maxima.sourceforge.io/ [2] https://feb.kuleuven.be/public/u0003131/WBT23/wxMaxima/wxM_intro/the_single_quote_operator.html https://feb.kuleuven.be/public/u0003131/WBT23/wxMaxima/wxM_i... [3] https://feb.kuleuven.be/public/u0003131/WBT23/wxMaxima/wxM_intro/the_double_quote_operator.html https://feb.kuleuven.be/public/u0003131/WBT23/wxMaxima/wxM_i... [4] although (in my limited experience) maxima sometimes refuses to evaluate anyway even if you do the double quote thing
- zelphirkalt 3y agoIs this correct though? Lisp's quote would need some eval or something to evaluate later afaik. More fitting might be a (lambda () ...), a.k.a. lazy evaluation.
- tsimionescu 3y agoThe implementation of the if() function would be the one that calls eval() on the true or false code block.
- gumby 3y agoLambda is a special form
- Zambyte 3y agoI would imagine it is closer to lambda than quote (though also a special form), since the implementation of if would require that the bindings in the arguments evaluate to their values in the callers environment.
- deleted 3y ago[deleted]