4 ms·
(author of Spry) Just a few notes: I like the cleanliness of Lisp, but I have always found it hard to read. That's one reason for Spry to have a bit more synta
by gokr 10y ago
(author of Spry)
Just a few notes:
I like the cleanliness of Lisp, but I have always found it hard to read. That's one reason for Spry to have a bit more syntactic elements than Lisp.
Spry supports both prefix and keyword style function calls, although as a Smalltalker by heart I favour keyword style.
Finally, Spry is still an evolving experiment. Next up is the OO model which I hope will be interesting.
- epidemian 10y agoThe language is quite interesting! The responses on this thread have been quite a letdown so far though :( You mention that the OO model is not yet implemented, however, there are a few snippets of code on the homepage that look like OO. I can understand that when you implement `select:` as an infix function then `[1 2 3] select: [something]` is dispatched to that function instead of using polymorphic dispatch on the "receiver". But, how are things like `clone` or `whileFalse:` implemented? Are they primitives? Are they using some other primitives under the hood? I'm asking because while syntactically it looks like Smalltalk, i don't see how it could work the same way if there's no OO system under the hood. In Smalltalk, something like `whileFalse:` would be implemented as a method on the condition block, which, in turn, would execute itself and decide whether to recur or not by sending an `ifTrue:` (or `ifFalse:`) message on the resulting boolean. And the polymorphic implementation of that `ifTrue:` message on booleans would ultimately cause the loop to stop or not. In other words: there's no primitive "if", nor loops, on Smalltalk; it's message sending all the way down. Do you envision having some similar all-encompassing design principle on Spry too? Also, kind of side note: i noticed that you're using the same syntax for blocks and lists. I understand this is something inherited from Rebol/Red, but i haven't used that language, so i don't really grok how that works. It's not something that most mainstream languages share, do you think you could dedicate some part of the language manual to explaining how can lists and blocks be "the same thing"? :D
- gokr 10y agoThanks! And oh, for longer discussions do pop in on gitter, gokr/spry. Some attempts at answers: Yes, the select: there is not polymorphic, it's simply a function (as of right now). clone is a primitive function, can be seen here: https://github.com/gokr/spry/blob/master/src/spryvm.nim#L1804 https://github.com/gokr/spry/blob/master/src/spryvm.nim#L180... (search for "clone" on that page to find the Nim implementations for the various basic node types) whileFalse: is also a primitive and can be seen here: https://github.com/gokr/spry/blob/master/src/spryvm.nim#L1904-L1911 https://github.com/gokr/spry/blob/master/src/spryvm.nim#L190... So yes, these are examples of primitive Spry functions that are implemented in Nim. Regarding the larger question, you can implement control structures in Spry, but they are obviously quite a lot slower. Also, it's worth noting that whileTrue: and friends are normally in Smalltalk implemented using special case bytecode tricks (jump). But you are correct in wondering about polymorphism, and Rebol doesn't AFAIK have anything like it - Carl shunned OO when creating Rebol. In Spry I am working on a concept of tags and what I call polyfuncs. Any node can have one or more tags added to it and functions can have multiple sub functions dispatched over based on these tags. The basics of this already works: https://github.com/gokr/spry/blob/master/src/sprytest.nim#L458-L459 https://github.com/gokr/spry/blob/master/src/sprytest.nim#L4... Hard to read I guess, but it basically creates a polymorphic function "inc" that has two different sub funcs selected based on the tag of the receiver. So about "design principle" - both yes and no. Spry is more "shallow" than typical Smalltalks because Spry is being implemented much more tightly together with Nim. This is by design, it makes it MUCH easier to make primitives and to interface with Nim and thus also C/C++. It's already trivial to do, and a lot of the examples show that. But I also want Spry to feel similarly "coherent" as Smalltalk does. And yes, definitely will describe the block/list thing in the manual. Too bad this HN post happened before the manual is out there, but oh well. But generally this is what homoiconicity means - code is in the same format as the core data structures. You can thus create and manipulate code as lists - just as in Lisp.
- draegtun 10y ago>> ...about polymorphism, and Rebol doesn't AFAIK have anything like it - Carl shunned OO when creating Rebol. Rebol does have objects, that's what the O in Rebol refers to. Their prototypal objects influenced by the Self language. And it also has polymorphism "built-in" [1] via its datatypes. However there doesn't seem to be a mechanism to extend or add your own. I guess the plan was probably to make use of the utype! datatype [2] penned for Rebol 3. I think Carl Sassenrath is fine with OO but just doesn't like how most OO languages work [3]. [1] action! datatype - http://www.rebol.com/r3/docs/datatypes/action.html http://www.rebol.com/r3/docs/datatypes/action.html [2] utype! - http://stackoverflow.com/questions/26780398/whats-known-about-utype-in-rebol-3 http://stackoverflow.com/questions/26780398/whats-known-abou... [3] The problem with OOL is not the OO - http://www.rebol.com/article/0425.html http://www.rebol.com/article/0425.html
- gokr 10y agoWell, when I talk about polymorphism I of course mean the ability in the language to create first class polymorphic constructs. Hardwired things like [1] doesn't count :) Further, I had read the article [3] and it seems to me that he indeed "rejected" OO in large parts after having worked with Smalltalk. That's quite intriguing (or astounding!) to me - since I agree that most so called OOP languages misses a lot of the story when compared to Smalltalk. Personally I find polymorphism and encapsulation together with strong abilities of abstraction to be the key aspects of OO and I have never found any language that captures these things better than Smalltalk. At the same time I also find Rebol's focus on DSLs to be very interesting - and as many may know this was also a big part of Alan Kay's FONC project. In Spry I want to combine both. In contrast to Carl I embrace the original ideas of OO as manifested in Smalltalk. However, I couldn't care less of a lot of the overcomplicated mess that so called other OOP languages have created since then, and I also think the beauty of Smalltalk can be captured differently, for example without classes.
- Chyzwar 10y ago1 to: 5 do: [echo :x] in smalltalk translate to: 1 to: 5 do: [:x | Transcript show: x ] 1(smallInt object) receive message 'to' with parameter 5 (smallInt object) return numeric range, then you send 'do; message with parameter being a block that evaluate for each element in range. Smalltalk is about objects and message passing. Spry only use Smalltalk syntax.
- ithkuil 10y agonitpick; that what you described is: (1 to: 5) do: [:x | Transcript show: x ] there is actually a to:do: method in the Number class, for example see the GNU smalltalk documentation: https://www.gnu.org/software/smalltalk/manual-base/html_node/Number_002dshortcuts-and-iterators.html#Number_002dshortcuts-and-iterators https://www.gnu.org/software/smalltalk/manual-base/html_node...
- Chyzwar 10y agobut internally to:do: is implemented as from:to:by: and do: with is almost the same.
- gokr 10y agoWell, Spry is much more Smalltalk than "only use Smalltalk syntax". But I have an entire article being written on that subject :) And no, your description of how it works in Smalltalk is wrong - #to:do: is implemented in the receiver (1). In Spry we are calling an infix function named to:do: and the only real difference to Smalltalk in this case is the fact that the dispatch of to:do: is not polymorphic. But as I described in other comments I am working on polymorphic functions as a way to reach similar abstraction levels.
- Chyzwar 10y agoThe thing is that Smalltalk do not have language constructs like loops or conditionals ifs/switch. Smalltalk also do not have functions only methods. There are only objects and messages. Your infix functions would need to live somewhere probably in global scope with makes then no different than language constructs. I would love to see new Smalltalk implementation that is not a Walled Garden. Making a Smalltalk impure is not a way foward imo. You work is interesting but what we need is Smalltalk VM on modern back-end like LLVM and better concurrency.