Hacker News new | past | comments | ask | show | jobs | submit login

I'm also unable to identify something unique about objecitve-S that makes it suitable for "well architected programs" compared to what we do in ST already. I learn languages for new ideas .. and I tried hard looking for one here. Sometimes such new ideas are hidden, as I discovered was the case with Julia - where multiple dispatch combined with just-ahead-of-time compilation opened up so many opportunities for fantastically collaborating libraries .. in a (for me) unexpected way.



Thanks for the feedback, and I am sorry that you couldn't find it. The site is both a bit slapped together (I didn't submit it) and lags behind the actual project, which itself is a work in progress. So what's documented on the site tends to be the more mundane stuff.

The papers go into a bit more detail, http://objective.st/Publications/ but the academic publishing process is also slow.

Another difficulty is that it is really different, but (or therefore) in unexpected places. Coming from Smalltalk background, I would be looking primarily at what it does with messaging and objects, and there Objective-S is almost completely unremarkable. It has HOM built in, but that would be easy to add, it uses {} instead of [] for blocks and has some actual syntax for defining methods and classes. Whatever. ¯\_(ツ)_/¯

The interesting stuff starts with the polymorphic identifiers, the URIs. Which, coming from a Smalltalk background I would probably note as being slightly funky, but then move on to get to the interesting bits, because identifiers in Smalltalk aren't particularly relevant.

However, URIs are foundational to the REST architectural style, which turns the Smalltalk idea on its head: interfaces are state-oriented (GET, PUT, DELETE as verbs + complex identifiers), computation is hidden. In Smalltalk, interfaces are "computational" (message-based) and state is hidden. With ObjS, you can easily express systems in an in-process REST architectural style. See the "Storage Combinators" paper linked from the site and the "In Process REST at the BBC" book chapter (https://link.springer.com/chapter/10.1007%2F978-1-4614-9299-...)

There are also what I call "property paths", which can be used in store definitions. They're kind of like the URL routes you find in frameworks like Flask, Sinatra, Rails, but generalized and integrated into the language. In-Process REST :). These I haven't put on the site at all yet, partly because I haven't gotten around to it, partly because they're not published yet.

Here is a short example, which adapts some introspection functionality as a store/scheme/in-process REST "server".

   scheme ClassBrowserAdapter  {
   
     /. { 
        |= {
               MPWClassMirror allUsefulClasses collect name.
        }
     }
   
     /:className/instanceMethods { 
        |= {
               mirror := MPWClassMirror mirrorWithClassNamed:className.
               mirror methodMirrors collect name.      
        }
     }

     /:className/classMethods { 
        |= {
               mirror := MPWMetaClassMirror mirrorWithClassNamed:className.
               mirror methodMirrors collect name.      
        }
     }
   }

This can then be served via HTTP, plugged into a generic GUI browser (which also browses filesystems) or combined with other storage combinators. Again, the paper gives a lot more detail.

Another example is from some recent experimentation with a Raspi I just wrote about (https://news.ycombinator.com/item?id=27099738). With a simple store, I can use the following code to turn on a GPI pin (hooked up to an LED):

    gpio:17 ← 1.
OK, sort of nice, but so what? Well, I can connect things up, so if I wanted to get the LED to blink, I would hook up the pin to a blinker object:

   blinker → ref:gpio:17
The → is a generic "connect these two things" operator, so maybe the generic "connector". In this case, it is connecting two dataflow components: the blinker is a source that repeatedly outputs alternating ones and zeros, and the ref: is a reference to the variable in question, rather than the value itself, and any variable can act as a sink, writing to it just sets the value.

I could also connect the blinker to stdout:

   blinker → stdout.
In which case it starts writing 01010101... to the console. I can also connect the blinker to a file:

   blinker → ref:file/tmp/alternating.txt
In this case, the file contents will oscillate between 0 and 1. And so on and so forth for dataflow-ish types of architectures. Of course, that also works for connecting up UIs. Note

So that's three architectural styles that are supported naturally by having the required connectors at hand:

1. Standard call/return in the form of Smalltalk-style messaging, extended with HOM

2. (In-Process) REST with stores, storage-combinators and property paths, supported by polymorphic identifiers

3. Dataflow, also supported by PIs.

And it turns out that with PIs, dataflow and storage-combinators, you get dataflow constraints almost for free, so that would be (4). In addition, there are notification protocols, which adapt between messaging and implicit invocation (5).

I hope this helps.


This is useful! Thanks for writing this out. I find in-process REST intriguing as it stands a little in contrast with OOP techniques. One possibility I’ve found with in-process REST is that it seems to make live patches feasible - more feasible than in erlang. I use the idea as the core of Inai - https://github.com/imaginea/inai (post describing it https://labs.imaginea.com/inai-rest-in-the-small/) ... so am curious to play with that aspect of ObjS.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: