What is the connection between OO and infix vs. FP and prefix? Most FP languages use infix notation for operators, and Haskell even supports infix notation for all functions. Lisp does both OOP and FP in prefix notation.
I think in that way it would make sense to say that procedural is also prefix, then, since even very procedural languages like C use VSO. Some OOP languages use VSO too (Perl's indirect object syntax, Common Lisp with CLOS, etc.) And someone could write all their Haskell as:
1 `elem` [1, 2, 3]
is a common way of calling elem in Haskell, and many times functions are redefined as operators (such as <$> instead of fmap, that gets used a lot more often). I just think that any kind of split with syntax based on paradigm seems very artificial to make.
Somewhat related, hy (aka hylang) is a lisp that compiles to the python abstract syntax tree which technically makes python a multi-syntax language already. Plus you get all the python libraries.
Hey, you're the guy you did hermetic! Looking at your project, along with Smallshire's Hindley-Milner blog post, have been a big help to me as I use Python to build a compiler/interpreter for an ML.
I was just planning to make a mini-ML to prepare for a larger project that requires type inference, but it's getting a bit addictive so I might just finish it off to match (most of) the Standard ML spec.
Anyway, well done on hermetic. It's a great start to my ideal Python, and where I'd like to see it move for 4.0 (although it will never happen).
Ha, I didn't expect that people remember Hermetic, I am glad it helped :]
Actually I took in a different direction with Hermetic, and now I have a type-infered python with a more classical type system and a language-independent code generator, compiling to Go, C# and Ruby. It can translate parts of standard library to equivalents in targets standard libraries, so it's a bit more practical, but I hope I can extend that somehow to Haskell support too: https://github.com/alehander42/pseudo-python
Your work seems pretty interesting, I'd love to chat sometimes about it
Of course you won't get out what you put in, but you might get something.
What I found most impressive was this scheme interpreter written in minikanren (schemes prolog) that can produce quine simply be expressing them as logic constraints over multiple programs.
Interesting. Yes, in some cases decompilation can return a higher level code than the original, which is quite an interesting an yet very much unexplored area. I only scratched that while I was working on a static code analysis.
Awesome! This has long been a dream of mine, but I never solved the problem of creating a better syntax than BNF grammars etc.
I don't know if we have the same goals, but my end-goal was to have some treelike serialization (JSON/XML) but a canonical editor which would display in whatever you were most familiar with (Lisp, Python, Haskell, C-ish). The limitation would be that you'd have to store metadata-ish stuff on the tree to handle custom indentations that don't follow some canonical style guide.
I like these type of things but I don't believe they are practical because of the massive potential variation within a single syntax which is typically hidden by language specific culture, convention and idiom. When you transliterate from one language to another, the gulf is made visible and the resulting code is alien and unacceptable despite executing correctly.
The unavoidable problem is finding a language in which every one's solution to the same problem is the same but I think that goal is more likely provably false than possible. If it is possible then finding solutions in such a language might be like threading a tiny needle and too hard to use.
Well, you mean the Zen of Python's "There should be one-- and preferably only one --obvious way to do it."
In any case, even then, people think in different ways: you can model a problem via category theory, geometry, algebra, and those would never translate into the same syntactical constructions, since the abstractions are of fundamentally different natures.
Now I think mostly in a functional way, so my Python code is full of small functions to help write "pythonic functional code", e.g. the function iff(b,x,y) that returns x if b and else returns y. The resulting code could be translated algorithmically to a functional language in a very natural way; the internal def would be translated to where clauses, etc.
The point being, I want to be able to think in the way that is the most adapted to tackle a problem, even if the code seems to be written in two different languages. This is no different from mathematics where each "X theory" is essentially its own language and each implies its own set of natural theorems.
>> This is no different from mathematics where each "X theory" is essentially its own language
Nice connection between models and languages.
The maths/physics discoveries achieved by using a new representation of a problem don't change the problem, they just present the issue at hand simply enough to be tractable. Each representation moves complexity trade-offs to a different category of problem.
I guess that does say something in favour of automatic syntax conversions but it seems too low level. Maybe conversions between the mode of abstraction being used is where it gets interesting.
In mathematics, there are fairly few such 'meta-results', and each one is duly celebrated as impressive; the one that comes to mind is Curry-Howard correspondence... but in more 'traditional' maths, it's very hard to find general high-level translations.
There are many cases where automatic syntactic low-level constructions can bring huge improvements, in compiler design, etc, it's more that they are less susceptible to be directly useful to laymen.
That's correct, I made it because I wanted to illustrate an idea.
However I think it can still be useful, and already there are precedents: semi-visual languages with underlying text source, lisp bi-directional macroses.
Do you think my another hivemind idea can be useful? Regrouping code based on structure and intent
(e.g. Group source by class / by method / in groups of highly-connected components)
>> I think it can still be useful, and already there are precedents
I have used some of these precedents so I guess I know their limitations. I have used and loathe visual languages (Ladder logic, Labview, Simulink) and consider them to be a dead-end that attracts too many people just because they are pretty. I have created and used one-way code visualisation tools which can be occasionally useful. They however have many degenerate cases where the automatic visualisation of fairly simple code is totally unreadable for me to believe there is much value in reversibility.
>> Do you think my another hivemind idea can be useful? Regrouping code based on structure and intent
Possibly. I use a few automatic tools for querying code and structure which are useful but given they lose the "designed to be understood" feature of hand-crafted information structure, they are only limited support tools to help solve specific problems. For example to get a handle a new huge code case, I use doxygen to create call-graphs from static analysis and profilers to create call-graphs from dynamic behaviour. Things like stats of hit-counts on various parts of a code-base can teach you a lot in seconds that is hard to grok from just reading code.
I believe that creating content for communicating understanding is a huge design challenge. Its really hard when its just 1000 words of text or a small UI but when its a 1M loc code-base its a gargantuan challenge. The fundamental conceptual break down, modularisation, choice of interfaces etc. is what distinguishes good codebases from unmaintainable ones. I don't see a code base as a sea of facts which you can understand with query tools. IMHO "designing to be understood" is a greater challenge than "designing to work".
I would be excited if you were thinking of a tool that could say analyse connectivity within and across modules and identify alternative high level structures that would simplify an architecture for human understanding. It feels like a graph clustering problem within the realm of modern data analysis.
Nim has a powerful templating system that allows introducing new syntactic elements and semantics, but maybe you are thinking about generating output code in multiple languages (C, C++, JS...)?
Bidirectional parsing-pretty-printing is a nice thing, with the only potentially tricky issue in an idiomatic rendering of the infix opetators with priority. Firstly, parser must be aware that they are special (I am using a dedicated Pratt parser for the binaries inside a Packrat for this reason). Secondly, it is often important to print parenthesis around an expression for readability, even if it is not dictated by the priority.
BTW the "if" in Python is very different to the "if" in lisp as one is a statement and the other is an expression. I'm curious how the OP plans to deal with the expression != statement.
This is very cool. People who want to create new languages usually have to write a lot of code even though most of the heavy lifting is done by a lexer and a parser generator.
This seems to me like a very high level way to specify a new language. A much easier way, definitely. I assume the cost of this is that only a small subset of programming languages can be specified in hivemind. Nevertheless, it's still an incredible project. Target LLVM, and this could become a compiler generator ;-).
39 comments
[ 4.7 ms ] story [ 102 ms ] threadSVO/OO/Infix: subject.verb(object)
VSO/FP/Prefix: (verb subject object)
SOV/RPN/StackOriented/Suffix: subject object verb
https://github.com/hylang/hy
It's been posted a bunch of times on HN
https://www.google.ca/search?q=site%3Anews.ycombinator.com+h...
Actually I've done a prototype of a lisp compiling to python bytecode, so that's why when I found hy, I was pretty excited about it.
https://github.com/alehander42/bach
However it's not making it multi-syntax in the same way, because you don't get 1-to-1 python-hy inter-translation.
I was just planning to make a mini-ML to prepare for a larger project that requires type inference, but it's getting a bit addictive so I might just finish it off to match (most of) the Standard ML spec.
Anyway, well done on hermetic. It's a great start to my ideal Python, and where I'd like to see it move for 4.0 (although it will never happen).
Actually I took in a different direction with Hermetic, and now I have a type-infered python with a more classical type system and a language-independent code generator, compiling to Go, C# and Ruby. It can translate parts of standard library to equivalents in targets standard libraries, so it's a bit more practical, but I hope I can extend that somehow to Haskell support too: https://github.com/alehander42/pseudo-python
Your work seems pretty interesting, I'd love to chat sometimes about it
Your work does, too. Yes, we should talk. My email's in my HN profile.
http://cs.brown.edu/~sk/Publications/Papers/Published/pk-res...
and more recently:
http://cs.brown.edu/~sk/Publications/Papers/Published/pk-hyg...
Then we could transpile every language into every other language, as long as it compiles to a common platform.
Using a logic language for implementation might help, but a compiler is probably not surjective in general which makes this very hard :(
What I found most impressive was this scheme interpreter written in minikanren (schemes prolog) that can produce quine simply be expressing them as logic constraints over multiple programs.
http://www.infoq.com/presentations/miniKanren
https://www.cs.indiana.edu/~eholk/papers/sfp2012.pdf
It's a great tool.
I don't know if we have the same goals, but my end-goal was to have some treelike serialization (JSON/XML) but a canonical editor which would display in whatever you were most familiar with (Lisp, Python, Haskell, C-ish). The limitation would be that you'd have to store metadata-ish stuff on the tree to handle custom indentations that don't follow some canonical style guide.
I also imagined automated reordering of code in an editor, but I still have only a demo (https://github.com/alehander42/rehab)
The unavoidable problem is finding a language in which every one's solution to the same problem is the same but I think that goal is more likely provably false than possible. If it is possible then finding solutions in such a language might be like threading a tiny needle and too hard to use.
In any case, even then, people think in different ways: you can model a problem via category theory, geometry, algebra, and those would never translate into the same syntactical constructions, since the abstractions are of fundamentally different natures.
Now I think mostly in a functional way, so my Python code is full of small functions to help write "pythonic functional code", e.g. the function iff(b,x,y) that returns x if b and else returns y. The resulting code could be translated algorithmically to a functional language in a very natural way; the internal def would be translated to where clauses, etc.
The point being, I want to be able to think in the way that is the most adapted to tackle a problem, even if the code seems to be written in two different languages. This is no different from mathematics where each "X theory" is essentially its own language and each implies its own set of natural theorems.
Nice connection between models and languages.
The maths/physics discoveries achieved by using a new representation of a problem don't change the problem, they just present the issue at hand simply enough to be tractable. Each representation moves complexity trade-offs to a different category of problem.
I guess that does say something in favour of automatic syntax conversions but it seems too low level. Maybe conversions between the mode of abstraction being used is where it gets interesting.
There are many cases where automatic syntactic low-level constructions can bring huge improvements, in compiler design, etc, it's more that they are less susceptible to be directly useful to laymen.
However I think it can still be useful, and already there are precedents: semi-visual languages with underlying text source, lisp bi-directional macroses.
Do you think my another hivemind idea can be useful? Regrouping code based on structure and intent
(e.g. Group source by class / by method / in groups of highly-connected components)
I have used some of these precedents so I guess I know their limitations. I have used and loathe visual languages (Ladder logic, Labview, Simulink) and consider them to be a dead-end that attracts too many people just because they are pretty. I have created and used one-way code visualisation tools which can be occasionally useful. They however have many degenerate cases where the automatic visualisation of fairly simple code is totally unreadable for me to believe there is much value in reversibility.
>> Do you think my another hivemind idea can be useful? Regrouping code based on structure and intent
Possibly. I use a few automatic tools for querying code and structure which are useful but given they lose the "designed to be understood" feature of hand-crafted information structure, they are only limited support tools to help solve specific problems. For example to get a handle a new huge code case, I use doxygen to create call-graphs from static analysis and profilers to create call-graphs from dynamic behaviour. Things like stats of hit-counts on various parts of a code-base can teach you a lot in seconds that is hard to grok from just reading code.
I believe that creating content for communicating understanding is a huge design challenge. Its really hard when its just 1000 words of text or a small UI but when its a 1M loc code-base its a gargantuan challenge. The fundamental conceptual break down, modularisation, choice of interfaces etc. is what distinguishes good codebases from unmaintainable ones. I don't see a code base as a sea of facts which you can understand with query tools. IMHO "designing to be understood" is a greater challenge than "designing to work".
I would be excited if you were thinking of a tool that could say analyse connectivity within and across modules and identify alternative high level structures that would simplify an architecture for human understanding. It feels like a graph clustering problem within the realm of modern data analysis.
And yes with Racket you can mix and match languages and create them with out parenthesis (https://docs.racket-lang.org/guide/languages.html).
BTW the "if" in Python is very different to the "if" in lisp as one is a statement and the other is an expression. I'm curious how the OP plans to deal with the expression != statement.
This seems to me like a very high level way to specify a new language. A much easier way, definitely. I assume the cost of this is that only a small subset of programming languages can be specified in hivemind. Nevertheless, it's still an incredible project. Target LLVM, and this could become a compiler generator ;-).