ikigai-go / compiler

Ikigai compiler
MIT License
0 stars 0 forks source link

How to core an apple #10

Open alfonsogarciacaro opened 5 years ago

alfonsogarciacaro commented 5 years ago

https://www.wikihow.com/Core-Apples

My first idea was to create a "pure" compiler without any dependency to a core library. But at a minimum we need an immutable list if we want to provide some native support for it (e.g. pattern matching, :: operator). If we do count on a (minimal) core library, I'd like to have the library separated from the compiler but then we need to make some decisions:

MangelMaxime commented 5 years ago
  • Do we force the user to add an import statement for the core library in every file or do we add it implicitly?

I think we should import it implicitly. So the user can just use it using List.filter.

  • If done implicitly, should the location of the core library (probably @ikigai-go/core) be configurable?

No, I see no benefit for that. If we integrate with the JavaScript tools (and my memory is correct) yarn and npm already provide ways to test a local package. It's possible to say that use folder XXX on my computer for @ikigai-go/core.

  • Should the core library members be available globally by default? If so, should this be a mechanism that can be used with other libraries? (something like import * into scope from "my-library")

I am not sure to understand but I want the user to write List.filter and not just filter.

  • Should we implement some constructs (like while, for loops) as core lib functions to simplify syntax?

It can simplify the syntax but reduce the opportunity to do an optimisation pass. So I am not sure.

alfonsogarciacaro commented 5 years ago

I am not sure to understand but I want the user to write List.filter and not just filter.

Yes, the issue is the core library will likely contain other things than a list so in standard JS we would have to do import * as Ikigai from "@ikigai-go/core" and then type Ikigai.List.filter which doesn't look nice.

BTW, you just reminded me that, if we want to promote the type with module helpers pattern we need a way to solve the naming of the type and the module (which F# does by adding the Module suffix in compiled code).

For example, if this is List.iki (tentative syntax):

class List<T> ...

export let filter<T> (f: T=>boolean, xs: List<T>) =
    ...

How do we import it? If we just do import * as List from "@ikigai-go/core/List.iki" the type name would become List.List. To avoid that, when List is used in type position we can just unfold it as List.List automatically.

It can simplify the syntax but reduce the opportunity to do an optimisation pass. So I am not sure.

I was thinking the compiler should do that, although having to use functions for the guard and the bodies can be a bit tedious.

do while(() => aCondition(), () => aBody())

At a minimum, I'd like to implement only for x of ... syntax and have a rangeInclusive or rangeExclusiveEnd in the core library that can later be optimized by the compiler:

for x of rangeInclusive(1, 100) do
   ...

// in JS becomes
// for (let x = 1; x <= 100; x++)
MangelMaxime commented 5 years ago

How do we import it? If we just do import * as List from "@ikigai-go/core/List.iki" the type name would become List.List. To avoid that, when List is used in type position we can just unfold it as List.List automatically.

I think we will need to make some test for this one and see how to goes. I guess this is how it's done in F#.

For example, in the Set.fs they implementation type Set under module Set. And then let filter ... under the module.

I like having rangeExclusiveEnd explicit even if not everyone will like that :D I do think explicit is undervalued in general.