This reminds me of Guarded Dependent Type theory, which isn't about stream programming, but has the same dimension analysis built into it.
Guarded Dependent Type Theory (GDTT) has dimensions (called clocks), fby/sby (called later), clock quantification (to introduce new dimensions), and dimension analysis built into the type system in the form of "clocked universes" (type universes which depend on clocks). The latter is required for the semantics to make sense, but it also allows an implementation without implicit caching. In particular, GDTT does not have an analogue of first for all types, but only for those types which don't themselves depend on the clock parameter and this requires clock dependence to be tracked in the type system.
Maybe not so interesting for stream processing as is, but it could probably be extended along those lines...
> the expression 2 ∗ 3 has the sequence
{6, 6, 6, 6, 6, ...}
cited from the book linked by yvdriess
Where did I see that before, octave (ie matlab perhaps), erlang/elixir? I think I remember trying to limit an implicit loop by giving a scalar or an array of one element and not getting anything back because the loop was infinite.
People often say that one should learn Lisp/Prolog/Haskell to become a better programmer. Lucid and Multidimensional Lucid should definitely be added to that list. It just reconfigure your brain around loops and iteration spaces.
Without more context it seems to be a relic from the past... Can someone give more context or point me to an implementation, online manual or tutorial? Searching in google does not return much (a wiki page and companies which use the same name).
Lucid is a functional programming language from the '80s that took a very different approach. All variables are infinite streams of values. It is a grandfather of sorts of reactive programming. Although the book title claims it's a dataflow language, the original Lucid is more a type of reduction-strategy functional language with a twist (viz. they call it Eduction).
The authors later refined the idea with Multidimensional Lucid, which replaces a slew of special forms (e.g. next, fby) and better deals with complex nested iterations, essentially by introducing a eval-at-context operator (context being a vector of dimension values). The Multidimensional Programming (https://books.google.be/books/about/Multidimensional_Program...) book starts with the example of transposing a matrix without touching its values.
So happy to have stumbled upon this, this is truly awesome, a recounting of Lucid's creation and various details by one of its creators. Probably best to start at the beginning:
This stuff has a very direct line to the modern "FRP" ideas (with the exception of the actual FRP by Conal Eliot, which is actually quite different from what most of us call FRP, oh details...). And it's so much more cogent.
When I looked at it a while ago, I couldn't find a working implementation, so I banged on it until I got something that at least appeared to work (on OS X): https://github.com/mpw/pLucid-osx
Awesome! I'm curious to try out your implementation. When I first stumbled upon Lucid early this year it seemed fascinating, but hard to wrap my head around by just reading the examples. I searched for a version that would work on today's machines but came up short.
I was reading up on streams as found in RxJS at the time, and though I am not yet an accomplished stream-wrangler their power is clear. Streams (or something like them, since Lucid's dataflows are different) be a core part of a language struck me as a good idea, and having only heard about Reactive Extensions in the past couple years it was surprising that the first example of first-class streams I encountered was 30 years old.
Sorry, I see that my words were ambiguous: it's not my implementation. I just took the existing pLucid implementation (which wasn't working) and banged on it until it worked again.
I highly suggest reading the original book on Lucid. It completely changed my outlook on programming language design. Section 1.5 is also one of the more hilarious takes on programming culture I've come across, so if you don't read the whole thing, at least read through that little gem. A pdf of the book is linked elsewhere in this thread.
Ashcroft and Wadge also once wrote of U of Waterloo tech note called (as I recall) "Of Yea? The world's first sarcastic programming language". I remember it being really funny, but the only construct I remember is the "Come From" instruction - the sarcastic analogy of GoTo which was a sort-of hot topic back then. Wish I could find a link to the paper....
11 comments
[ 2.0 ms ] story [ 19.8 ms ] threadGuarded Dependent Type Theory (GDTT) has dimensions (called clocks), fby/sby (called later), clock quantification (to introduce new dimensions), and dimension analysis built into the type system in the form of "clocked universes" (type universes which depend on clocks). The latter is required for the semantics to make sense, but it also allows an implementation without implicit caching. In particular, GDTT does not have an analogue of first for all types, but only for those types which don't themselves depend on the clock parameter and this requires clock dependence to be tracked in the type system.
Maybe not so interesting for stream processing as is, but it could probably be extended along those lines...
cited from the book linked by yvdriess
Where did I see that before, octave (ie matlab perhaps), erlang/elixir? I think I remember trying to limit an implicit loop by giving a scalar or an array of one element and not getting anything back because the loop was infinite.
The authors later refined the idea with Multidimensional Lucid, which replaces a slew of special forms (e.g. next, fby) and better deals with complex nested iterations, essentially by introducing a eval-at-context operator (context being a vector of dimension values). The Multidimensional Programming (https://books.google.be/books/about/Multidimensional_Program...) book starts with the example of transposing a matrix without touching its values.
Here's the Lucid wikipedia page: https://en.wikipedia.org/wiki/Lucid_(programming_language)
The relatively ancient pLucid implementation can be found here: https://code.google.com/archive/p/plucid/
The original book's PDF can be found on various sites, such as Bret Victor's http://worrydream.com/refs/Wadge%20-%20Lucid,%20the%20Datafl...
https://billwadge.wordpress.com/2011/03/23/lucid-the-origins...
And then work your way forward. The book is also great: http://www.cse.unsw.edu.au/~plaice/archive/WWW/1985/B-AP85-L...
This stuff has a very direct line to the modern "FRP" ideas (with the exception of the actual FRP by Conal Eliot, which is actually quite different from what most of us call FRP, oh details...). And it's so much more cogent.
Also check out the Wikipedia page: https://en.wikipedia.org/wiki/Lucid_(programming_language)
When I looked at it a while ago, I couldn't find a working implementation, so I banged on it until I got something that at least appeared to work (on OS X): https://github.com/mpw/pLucid-osx
I was reading up on streams as found in RxJS at the time, and though I am not yet an accomplished stream-wrangler their power is clear. Streams (or something like them, since Lucid's dataflows are different) be a core part of a language struck me as a good idea, and having only heard about Reactive Extensions in the past couple years it was surprising that the first example of first-class streams I encountered was 30 years old.
Sorry, I see that my words were ambiguous: it's not my implementation. I just took the existing pLucid implementation (which wasn't working) and banged on it until it worked again.