Programming paradigms that change how people think about coding (2014)(ybrikman.com)
ybrikman.com
Programming paradigms that change how people think about coding (2014)
https://www.ybrikman.com/writing/2014/04/09/six-programming-paradigms-that-will/
12 comments
It's not strictly a programming language, but Scribble (a Racket language) is really the first document creation language that neither feels like a markup language with a programming language API nor a programming language with a document creation API. With this sort of setup, it is really easy to introduce arbitrary new constructs to avoid duplication or to better structure your document.
LaTex is the only system I know that comes close to this, but the language is pretty horrible to actually try and use (to be fair, LaTex has quite a bit of legacy it has to maintain).
LaTex is the only system I know that comes close to this, but the language is pretty horrible to actually try and use (to be fair, LaTex has quite a bit of legacy it has to maintain).
Slight nitpick only: The language that LaTeX is written in is TeX. LaTeX is a library of macros.
I didn't know about Scribble. I know what I'm doing with my weekend now. Thanks!
I didn't know about Scribble. I know what I'm doing with my weekend now. Thanks!
Prolog is declarative, but it's very different to SQL and it's a shame to put the two together. It is much more interesting to examine Prolog from the logic programming point of view.
Also:
1) The sorting example is O(n!) not because of limitations of the language, as the article suggests, but because the algorithm implemented is permutation sort, which is O(n!).
A typical sorting algorithm example in Prolog is merge sort which is as efficient in Prolog as merge sort can be. Here are a few sorting algorithms in Prolog, including merge sort and quick sort:
http://kti.ms.mff.cuni.cz/~bartak/prolog/sorting.html
2) The Sudoku example uses a Constraint Logic Programming library implemented in Prolog (from the looks of it, Gnu Prolog). CLP is a different paradigm than plain logic programming, where one programs by specifying constraints.
A Sudoku solver in actual Prolog can be found in "99 Prolog Problems":
https://www.ic.unicamp.br/~meidanis/courses/mc336/2009s2/pro...
The sudoku solver is number 97.
Also:
1) The sorting example is O(n!) not because of limitations of the language, as the article suggests, but because the algorithm implemented is permutation sort, which is O(n!).
A typical sorting algorithm example in Prolog is merge sort which is as efficient in Prolog as merge sort can be. Here are a few sorting algorithms in Prolog, including merge sort and quick sort:
http://kti.ms.mff.cuni.cz/~bartak/prolog/sorting.html
2) The Sudoku example uses a Constraint Logic Programming library implemented in Prolog (from the looks of it, Gnu Prolog). CLP is a different paradigm than plain logic programming, where one programs by specifying constraints.
A Sudoku solver in actual Prolog can be found in "99 Prolog Problems":
https://www.ic.unicamp.br/~meidanis/courses/mc336/2009s2/pro...
The sudoku solver is number 97.
Out of order calculation based on dependencies: mlet (magic let/mutual let) macro:
This is the TXR Lisp interactive listener of TXR 212.
Quit with :quit or Ctrl-D on empty line. Ctrl-X ? for cheatsheet.
1> (mlet ((w 3)
(x (+ z w))
(z (* 2 w)))
(list x z w))
(9 6 3)
Obligatory macro-expansion: 2> (macroexpand '(mlet ((w 3)
(x (+ z w))
(z (* 2 w)))
(list x z w)))
(let (#:g0011 #:g0012
#:g0013)
(symacrolet ((w (force #:g0011))
(x (force #:g0012))
(z (force #:g0013)))
(set #:g0011
(delay 3))
(set #:g0012
(delay (+ z w)))
(set #:g0013
(delay (* 2 w)))
(list x z w)))
Circular dep naturally fails: 1> (mlet ((x y) (y z) (z x)))
nil
2> (mlet ((x y) (y z) (z x)) x)
** (expr-2:1) force: recursion forcing delayed form y (source location n/a)I wrote the exact same macro in Clojure a couple weeks ago !
(defmacro lay [[sym expr & more-bindings] & body]
(let [delay-sym (gensym (str "laid-" sym "-"))]
`(let [~delay-sym (delay ~expr)]
(symbol-macrolet [~sym (deref ~delay-sym)]
~@(if (empty? more-bindings)
body
`[(lay ~more-bindings ~@body)])))))That expansion strategy won't work in TXR Lisp, because if we have
So y in (delay y) will not be expanded there as we need it to, which we need because the initializing expressions in mlet can refer to all the variables (including their own, if they are careful).
This is why the code binds all of the gensyms first, and then initializes them by assignment in a scope in which the symacrolets are all visible.
Using mlet plus some lazy structure like a lazy cons (lcons) we can do useful things:
(let ((#:g1 (delay y)))
(symacrolet ((x #:g1))
(let ((#:g2 (delay z)))
(symacrolet ((y #:g2))
...))))
the (delay y) expression is not in the scope of (symacrolet ((y #:g2)) ...). Local symbol macros are lexically scoped. They can shadow lexical variables and be shadowed by them and so on.So y in (delay y) will not be expanded there as we need it to, which we need because the initializing expressions in mlet can refer to all the variables (including their own, if they are careful).
This is why the code binds all of the gensyms first, and then initializes them by assignment in a scope in which the symacrolets are all visible.
Using mlet plus some lazy structure like a lazy cons (lcons) we can do useful things:
1> (set *print-circle* t)
t
2> (mlet ((lc (lcons 1 lc))) lc) ;; make a circular list
#1=(1 . #1#)This is not parallelized, but the blueprint is there.
Suppose we replace delay with an async opreator, and force with a corresponding await ...
The mlet macro is simple enough to be written in ... less than forty lines of readable C.
http://www.kylheku.com/cgit/txr/tree/eval.c?id=txr-212#n4217
Suppose we replace delay with an async opreator, and force with a corresponding await ...
The mlet macro is simple enough to be written in ... less than forty lines of readable C.
http://www.kylheku.com/cgit/txr/tree/eval.c?id=txr-212#n4217
[deleted]
The dependent types example seems underwhelming; rejecting arrays of unlike length at compile time is something I'd expect from a Pascal compiler from 1975.
How about C90: pointer to array of 10 is not compatible with a pointer to array 20:
How about C90: pointer to array of 10 is not compatible with a pointer to array 20:
int process_array(int (*pa)[20]);
int main(void)
{
int array[10];
process_array(&array);
return 0;
}
GCC: array.c: In function ‘main’:
array.c:6:17: warning: passing argument 1 of ‘process_array’ from incompatible pointer type [-Wincompatible-pointer-types]
process_array(&array);
^
array.c:1:5: note: expected ‘int (*)[20]’ but argument is of type ‘int (*)[10]’
int process_array(int (*pa)[20]);
^~~~~~~~~~~~~The goal is to get static time checking of dynamic types. For example, if I take two dynamic length arrays and loop n times, appending (optionally?) an element to each array, can you still provide a compile-time check that both arrays are necessarily the same length. It’s much more powerful than what you describe.
s/you describe/the submitted web page describes/
FTFYWhat I describe isn't being posed as "dependent types".
here's a full code example in Idris, demonstrating Dependent Types, that's not completely facile:
it's either a compile error or it's valid.
import Data.String
-- takes two integers, and a proof that x < y, and yields an integer
add :
(x : Integer) ->
(y : Integer) ->
(prf : x < y = True) -> -- require a proof that that x < y
Integer
add x y prf = x + y
main : IO ()
main = do
sx <- getLine -- read string from input
sy <- getLine -- read string from input
let Just x = parseInteger sx -- assuming int parse is ok, else error
let Just y = parseInteger sy -- assuming int parse is ok, else error
case decEq (x < y) True of -- decEq constructs a proof (prf) if x < y is True
Yes prf => print (add x y prf) -- yes, we got a prf, pass it to add
No => putStrLn "no prf, x is not less than y" -- the prf variable is not available in this case
lets say I mess up the sign of the comparison on the case line and write decEq (x > y) instead... then I'd get a type error When checking argument prf to function Main.add:
Type mismatch between
x > y = True (Type of prf)
and
x < y = True (Expected type)
there's no way to construct the prf value artificially, or sneak in different parameters that are unrelated to the prf value.it's either a compile error or it's valid.
Here's a dependent types example I found a little more interesting: statically modeling a valid date type: https://github.com/chrisdone/sandbox/blob/master/liquid-hask...
Too bad Behavioral Programming isn’t discussed as I find it to be the most fascinating one especially because its main objective is to better align programming to how humans think: https://lmatteis.github.io/react-behavioral/
Another strange language feature I could imagine seeing here: Constraint Logic Programming
Wolfram always impresses me but I can't help but feel like it will never go anywhere. How can it grow without being crushed under its own weight? As he stated in the video, its all hand crafted data set munging to fit it all together.
I'd love to see a world where wolfrom pulls on datasets out in the wild much like a search engine scrapes web pages but is such a thing possible? It begins to sound like a SOAP/WSDL fever dream when you think about automatic knowledge integration.
Maybe something closer to the open source package managers? Wolfram datasets could specify interfaces and dependencies? At least that would allow for new and exciting datasets to gain adoption in the community.
I'd love to see a world where wolfrom pulls on datasets out in the wild much like a search engine scrapes web pages but is such a thing possible? It begins to sound like a SOAP/WSDL fever dream when you think about automatic knowledge integration.
Maybe something closer to the open source package managers? Wolfram datasets could specify interfaces and dependencies? At least that would allow for new and exciting datasets to gain adoption in the community.
>Wolfram always impresses me but I can't help but feel like it will never go anywhere. How can it grow without being crushed under its own weight?
Why would it? It's not like a language pays for the storage of libs and datasets it has available.
>As he stated in the video, its all hand crafted data set munging to fit it all together.
It's also a system for symbolic math / functional programming language that's independent from all the "hand crafted data sets".
>I'd love to see a world where wolfrom pulls on datasets out in the wild much like a search engine scrapes web pages but is such a thing possible?
It can already pull anything you want (ingest CSV files, call remote JSON APIs and crunch the data, etc).
It's a regular programming language (lispy even), not some weird concoction.
It just comes prepackaged with an IDE and tons of libraries and datasets.
Why would it? It's not like a language pays for the storage of libs and datasets it has available.
>As he stated in the video, its all hand crafted data set munging to fit it all together.
It's also a system for symbolic math / functional programming language that's independent from all the "hand crafted data sets".
>I'd love to see a world where wolfrom pulls on datasets out in the wild much like a search engine scrapes web pages but is such a thing possible?
It can already pull anything you want (ingest CSV files, call remote JSON APIs and crunch the data, etc).
It's a regular programming language (lispy even), not some weird concoction.
It just comes prepackaged with an IDE and tons of libraries and datasets.
Could you please edit personal swipes out of your comments to HN? Your post would be excellent without the first bit.
https://news.ycombinator.com/newsguidelines.html
https://news.ycombinator.com/newsguidelines.html
We detached this subthread from https://news.ycombinator.com/item?id=19334606 and marked it off-topic.
Anyone that has used a third-party API or written a parser understands all they need to about declarative languages...
> It’ll be very interesting to see if the symbolic programming model is as flexible as Wolfram claims and can truly take advantage of all of this data.
Wolfram could have implemented his large standard library also for any other ecosystem. The magic of this library (which goes along with Wolfram's Lisp dialect but is considered as a unit) is that it is extremely high level, allowing rapid application development. But as with most libraries, it could have been developed for any language/idiom, such as a traditional object oriented python.
Wolfram could have implemented his large standard library also for any other ecosystem. The magic of this library (which goes along with Wolfram's Lisp dialect but is considered as a unit) is that it is extremely high level, allowing rapid application development. But as with most libraries, it could have been developed for any language/idiom, such as a traditional object oriented python.
My 2 cents is that Mathematica and the Wolfram language are great for computational exploration (Ex: optimization, solving equations, plotting, statistics, calculus...etc etc). I think all the stuff that they really like to sell (Ex: the knowledge engine) are a gimmick. Yeah it can tell me how many calories are in spaghetti, but honestly...who cares? Normally, you would just get that in a dataset anyway which is more transparent. All my data is extremely private too, and they'll never have it available.
The explorative character of the MMA/Wolfram language is probably mostly due to the "REPL on stereoids". IPython provides a similar attempt but is "traditional" OOP (with explorable documentation and members/methods). Therefore, I am not that sure about the unique selling point of Mathematica. From my POV it is the pure size of the library and thus power of expression evaluation, like finding the algebraic solution to a complicated integral.
I find it interesting that the discussion on Dependent Types lists Idris and Coq as languages and discusses Formal Verification but mostly focuses on Idris and Scala with Shapeless... but to my knowledge, Coq has actually won out in 2019 for this, and Coq has even branded itself for this specifically[0].
[0] https://coq.inria.fr/ - Coq is a formal proof management system.