moosekkcoral•

I am looking forward to write more about F in the future, but I probably won't implement it (not that good of a programmer actually)

Don't sell yourself short! The language design is very cool, like syntax sugar for Scheme in a way.

11
ac1235OP•

Well I never said I'm not a good language designer, did I ;)

I'm just not good at implementing my ideas. That's not selling myself short, that's knowing where my strengths and weaknesses are.

4
MegaIng•

I am currently starting to implement this and have a few questions:

  • What Symbols are allowed in names?
  • What Operators are allowed? Can you compose your own Operators? How are priorities of the operators?
  • Is there a notation for variadic/optional arguments?
  • What is with string escaping? The default backslash from c?
  • Is there a difference between float and integers?
  • What do you mean with this:

For convenience, this introduction assumes literal syntax for lists ({a b c}), strings ("hello world"), and numbers (12.3)

Is that syntax not fixed? Could/Should that change?

  • How are the scopes of the variables defined?
5
ac1235OP•

Wow this is really cool! I am realy vague at plafes where the end decision doesn't add to the feel of the core language. Basically all these decisions are up to you.

Except for scoping perhaps which I should clarify: since all variables are immutable (:=) always creates a variable in the inner most block/function.

If you are still interested in what I'd do (not that you have to follow my advice):

  • Symbols in names alphanumerics and underscore (but no number as first char)
  • Operators + - * / < > = <= >= <> with standard math precedence, although no user defined operators (things like mod could be written as a mod: b and infix function application has the lowest precedence)
  • I chose ... to mean rest of the arguments in the text, so [|...| argList := {...}; doStuff ()] has the intended effect of creating an argument list (a bit like in Lua)
  • Default C string escaping
  • Numeric types are up to the implementation, but I think there shouldn't be a user exposed difference. It's all just numbers.
3
MegaIng•

I now have the implementation finished to a degree where I would like to now your opinion on it. It is still hosted on github. I would like to hear if you find any bugs. All your example should work as expected.

2
ac1235OP•

Wow that's great! I will try it out as soon as I can :)

2
ac1235OP•

Okay I tried it now and it's great! However I also had to install pydot, which the README did not mention. But the software is wonderful and I'm impressed how well it handles the obscure syntax of F.

I will definitely fork your repo soon and test a few of my design ideas in my version of it.

What I'd like to know is if you are interested in maintaining your implementation and doing things like adding a REPL or turning it into an AST compiler (kinda like Hy works) or stuff like that. In that case I'd love to see a lot of your own ideas implemented too and I will keep you up to date with what I intend for the future, but in either case thank you a lot for your awesome work :-)

1
MegaIng•

I already have a first version uploaded as github. This is not finished (quite a few things missing or wrong), but I don't have any time to work on it for the next two weeks. (I may have time two answer issues) If you have questions ask.

2
ac1235OP•

This is really cool! And your code is very readable actually.

2
MegaIng•

I am happy to hear that.

1
tekknolagiKevin3•

How are you running this? Neither python 2.7 nor 3.6 work for me.

1
MegaIng•

I am using python3.7 because of the from __future__ import annotations. You can also remove this line, but then you may have to remove a few annotations. Also you need to install lark (pip install lark-parser)

1
spreadLink•

Maybe i missed it, but how does the language determine the amount of arguments passed? What about fixity?

How would (+) 1 2 3 + 4 be parsed?

4
MegaIng•

I believe as many arguments as possible are matched. Infix Operators have a higher priority then normal calls (hence the brackets around +).

3
ac1235OP•

You are right, all the arguments go to a function that can (a little bit like in shell scripts), but just like in ML function application has higher precedence than all operators, so sin x / cos x parses as (/) (sin x) (cos x).

1
spreadLink•

that's about what i expected, v nice.

​

One other question, i assume there's no concept for composite types except the array right?

2
ac1235OP•

Well, there is no reason why you couldn't have maps, bags, sets and what not. I think an actual implementation should also provide maps at least.

2
MegaIng•

That would mean that his example would be parsed as (+) ((+) 1 2 3) (4)? Then I misunderstood. I thought it would be parsed as ((+) 1 2 (+)(3 4))

1
ac1235OP•

Yes indeed

1
boomshroom•

Honestly, what I see here is a perfectly fine and usable language. I'm not entirely clear on what do does, but otherwise, it makes me more excited about functional programming. It is really cool how such a simple syntax can allow for the implementations of so many imperative constructs.

4
tripl3dogdareServal•

do appears to just be a "call this function" function. It's first argument is a function, and it passes all the arguments after that to that function. It's just a more explicit way to write it that's recommended for calling functions passed as arguments, probably in part for type-safety reasons.

3
ac1235OP•

Except for the type safety part (I did not think about that, but you might be on to something) this is exactly what I intended.

As a consequence of that do can also be used to create a lexical scope: do [ a := b; c ]. This is roughly equivalent to the (function(){...})() pattern in old JS code.

1
tripl3dogdareServal•

Quite similar to the let construct in most Lisps, too:

(let [ a (+ b c) ]
  ...)

Slight tangent, but as much as I still use it from time to time when it's needed, I really hate that pattern in JS... It's just a really ugly syntax for a concept that should be a lot simpler. It's gotten nicer with arrow functions, but (() => {...})() is still pretty nasty to look at, especially when people sprinkle it throughout their entire codebase in the most unsavory places imaginable.

1
ac1235OP•

Yeah in JavaScript it really is ugly, but I think that's because of the syntax do [ stuff ] looks pretty elegant to me actually.

2
VernorVinge93•

I like that your expression and block syntax is (at least roughly) the same.

Any particular reason for choosing "[" and "]" rather than "(" and ")"?

Also variadic functions seem nice but I don't know how they interact with a type system.

I only skimmed your write-up but what kind of type checking are you planning on?

2
ac1235OP•

Just to clarify I used the word block in the Smalltalk/Ruby meaning of the word. A block is a lambda is an anonymous function. I chose [] instead of {} because it looks more clean and is how other languages do it. Also if I chose curlies, I'd reassamble C enough that the differences would be confusing.

The language as it stands is dynamically typed.

2
VernorVinge93•

Cool. Thanks (both for the clarification and explanation)

1
ac1235OP•

Hey little question: do you feel the same about languages too closely reassambling C? In my mind, if something looks like C, I think like in C. This is a littpe bit of an issue though when the language behaves completely differently.

1
VernorVinge93•

Yeah, ideally things that look the same do the same thing.

E.g. i don't like pony's assignment operator (in "a=b" it evaluates to the old value of a, which a no longer holds).

Still. Some amount of breakages are necessary for progress, even if they cannot be introduced in some kind of clean/visually distinct manner.

1
dobesv•

I like the way if else works, it's very clever!

1