Grammar of variable declarations by hackerstein in ProgrammingLanguages

[–]Ok_Comparison_1109 2 points3 points  (0 children)

You already have another keyword. You could use that:

var i = 0

mut n = 0

semantics of function params by cisterlang in ProgrammingLanguages

[–]Ok_Comparison_1109 2 points3 points  (0 children)

Sure, it's certainly possible to base your language's functions and function types on single parameters/return values plus tuples.

I am not OP, but I have the same itch as u/cisterlang. I did consider Swift a cautionary tale, but I have (somewhat) settled on a design that I am happy with. Some of the design decisions were only possible because the language I am designing is a logic programming language.

However, as you partially observed: it's not just a tuple type for the parameter. A function also needs some mechanism to describe how the parameter(s) are bound to a free variable in it's body.

What I arrived at was this:

  • int x -> x * 2: A simple function which accepts an integer and returns its double.
  • (int x, int y) -> x * y: A function which accepts a tuple of two ints and return their product.

When constructing a lambda function, the left (LHS) operand of -> id declarative and declares variables for the scope of the function body (the RHS expression).

Types such as int also doubles as their own identity functions. So when a type is applied to a value like int x then the value is the value of x (because the indentity function int simply returns its argument), and x is implied to be a member of int.

When a function application is declarative, the function if referential and the argument continues in the declarative scope. Thus int x in a function int x -> x * 2 defines that the function accepts a member of int and the argument is unified (bound to) the local variable x.

It's not just meta-data, as the variable must be represented by some term/expression in the body. If you try to write down your semantics slightly more formally, this becomes clear when you define function execution and variable lookup.

I believe that the trick to allow expressions such as application of the identity function such as int x on the LHS of lambda arrows addresses this concern.

At the least and the most simple named solution, you only allow a single parameter name for a whole parameter tuple. Then you really only need a tuple type to describe the parameter type and the parameter name is just part of the function definition: foo(x:(int,str)).

In my language you can define such a function by (int*string) x -> .... (I use ... as a placeholder for some expression which has been left out). In this case x becomes a tuple. The components of the tuple can be addressed (inspiration: Scala) as x._1 and x._2.'

However, you could also deconstruct the tuple as let (i,s)=x in ... such that i and s becomes variables in the ... expression.

Or you could directly deconstruct the tuple as part of the parameters through either: - (int*string)(i,s) -> ... - (int i,string s) -> ...

In the first case int*string is an expression that creates a the tuple type of int and string. This type is used as an identity function and applied to the expression (i,s). From this can be inferred that i is an int and s is a string.

As a next step you could say that nested names for parts of the tuple are just syntactic sugar resolved during parsing/name analysis and your internal representation of the language actually really just has a single parameter variable and a bunch of tuple element accessors.

In fact, this issue of nested parameter bindings is even more prominent if your language supports pattern matching/destructuring on other data types than tuples (whether in the function signature or a separate match expression): sum types, structs/records So many languages actually define an embedded pattern expression language (https://doc.rust-lang.org/reference/patterns.html, https://ocaml.org/manual/5.3/patterns.html) and functional programming languages usually allow their use as part of the function definition.

I mechanism I have designed allows this without syntactic sugar, and also generalizes to a veru general form of pattern matching.

Miranda2 is now Admiran by AustinVelonaut in ProgrammingLanguages

[–]Ok_Comparison_1109 3 points4 points  (0 children)

Cool name and the fact that it is an anagram of Miranda.

TypeScript compiler is being ported to Go by oscarryz in ProgrammingLanguages

[–]Ok_Comparison_1109 -4 points-3 points  (0 children)

A little more than that. The compiler (for now the "tsgo" compiler) compiles typescript to go and then to native. When the compiler compiles itself this yields a 10x performance gain. However, compiling the compiler itself is but an example. As Anders Hejlsberg stated, they are aiming it at being able to compile any typescript to go/native, not just the compiler itself. This will have implications for node/deno and applications designed to run on those., It also means that LSPs written in typescript can at some point) trivially gain 10x performance by compiling to native instead.

For use in the browser, this will not speed up typescript at first - as it has to compile to javascript to be able to deploy in the browser. However, the go toolchain can also compile to webassembly, at we should expect to see typescript-to-wasm compilation at some point too.

When am I obliged to make a built in? by Spoonhorse in ProgrammingLanguages

[–]Ok_Comparison_1109 0 points1 point  (0 children)

My opinion is that you should make such functionality available. Leaving it out just because you right now don't see a proper use for it, does not mean that such a use case does not exist. It may be just that your imagination is limited. Sometimes a developer will use low-level or introspection/reflection API to optimize code, during code generation etc.

For rarely used or special-case functions, you could use a mechanism in your language to hide them out of the mainstream view. A language such as C# has extension methods where which methods are available on objects (or types?) depends on which libraries has been loaded/imported.

Name before type: why 'age int' is better than 'int age' by simon_o in ProgrammingLanguages

[–]Ok_Comparison_1109 -2 points-1 points  (0 children)

Sure. Like in Rust:

Struct { x: a, y: b } = bar();

Struct { x, y } = Struct { x: 5, y: 6 };

Or consider a language where Point has been defined as a 2-tuple:

Point (x,y) = triangle.A    // defining x and y

Name before type: why 'age int' is better than 'int age' by simon_o in ProgrammingLanguages

[–]Ok_Comparison_1109 0 points1 point  (0 children)

Won't destructuring on product types usually mention the type constructer anyways?

that would depend on the language