Thoughts on extending Euphoria language
- Posted by acEduardo Apr 21, 2017
- 1356 views
Some time ago I submitted here an idea of "structs", a form of light pseudo-object-orientation, for Euphoria. I tried to make a prototype. I've written some toy preprocessors for this, nothing using "euphoria/tokenize.e". Sadly just a bunch of bad code I'm too ashamed to share.
I was (and still am) too busy to seriously work on the subject, many changes occurred recently in my live.
I recently had the opportunity to use Lisp, and was mind-blowing! Both by the Lisp power, and by realizing the influences Lisp has on Euphoria.
And while revisiting my past experiences with functional langs, I started thinking how would be if Euphoria adopted the functional paradigm.
From this occasional thought, all of a sudden i realized that Euphoria statements and blocks are much alike Lisp forms. Or better, they are like "parenthesis-less forms".
What I mean is:
integer a = 3 /* (def a 3) */ -- or switch some_data do case 1 then fun1() case 2 then fun2() case 3 then fun3() end switch /* (cond ((= some_data 1) (fun1)) ((= some_data 2) (fun2)) ((= some_data 3) (fun3)) ) */
Why not let Euphoria become infected by functional paradigm? :)
Certainly Euphoria isn't exactly homoiconic, but i can easily imagine parenthesis around the vast majority of Euphoria constructs...
So i made some drafts!
-- Euphoria functionally inspired (or "lispy style") -- Let me temporarily call it "LEuphoria" -- Some changes: /* LEuphoria will have lambdas (nameless functions). These special functions become sequences, they'll be automatically serialized (converted into IL bytecode?). And they will gain and use the "routine" type. */ -- Example: routine my_lambda = lambda (integer a, integer b) return a+b end lambda ? my_lambda -- Prompts a sequence -- something like {1, {{1, "a"}, {1, "b"}}, {"b", "a", 34, 86}} -- What about modify "pretty_print()" ? ? my_lambda (1, 2) -- Prompts 3 /* LEuphoria will gain 2 new builtin functions: "compile()" and "execute()". "compile()" parses a single expression. It returns a valid "sequence"-type object (containing IL bytecode?) in case of success, or a atom in case of failure. Its return will not be a valid "routine"-type object, but it can be seen as a fragment of one (and used to modify a valid "routine"-type object, albeit somewhat clumsily...). "execute()" will receive a sequence (containing IL bytecode?) (potentially coming from a "compile()" invocation) and execute it in the actual scope, returning the calculated value (and potentially causing side-effects). */ -- Example: integer a = 1,b = 2,c = 3 sequence my_expression1 = compile ("a + b*5 - 4") ? execute (my_expression1) -- Prompts 7 object my_expression2 = compile ("get_some_fun(c)") -- returns a sequence but if executed will cause a -- "runtime exception: routine `get_some_fun` isn't defined". /* Some Euphoria statements become LEuphoria expressions. "switch" and "if" blocks return the value of the last evaluated expression in their bodies. I was thinking of a way to empower loops, but I could not come up with a satisfactory solution. */ -- Example: integer a = 1 integer b = if a = 1 then 2 else 3 end if -- b = 2 /* I don't know what to do with this: */ -- Example: routine abc = lambda ... end lambda abc += 3 -- O_O??
These constructions don't instantly turn "LEuphoria" into a "Lisp dialect", but enables some powerful capabilities.
About my last idea (about structs), I want to modify it. I'm thinking in a declarative way of create new types, combining existent types. Maybe something like:
type Person (sequence p) made of string name sequence likes end type type Worker (sequence w) made of Person who_i_am string what_i_do_here end type Worker John = {{"John", ""}, "something"} ? John.who_i_am.name -- Prompts "John" -- You can selectively unpack members using the "and" word after the member: -- (What about use the word "unpacked"?) type Worker2 (sequence w) made of Person who_i_am and -- will unpack this member string what_i_do_here end type Worker2 Bill = {"Bill", "", "something"} ? Bill.name -- Prompts "Bill"