Earlier quoted context omitted.
Haskell is a great language with a really advanced type-system, although I found its syntax hard to read at times especially as I was exploring the language at first. On the other hand I really liked how Rust syntax was defined in terms of ADTs, Traits & Methods Impls, with type signatures required for functions. Hence I wished for a similar functional language that has such write-style and type concepts, but strippi…
Just as general feedback, I think your experience matches up with more software developers than the GP. Haskell is really obtuse and unreadable for those who are not accustomed to it.
Show HN: Fuse – statically typed functional programming language
41–49 of 49 posts
Re: Show HN: Fuse – statically typed functional programming language
#42Just curious, what made you choose GRIN? I haven't heard of it but it looks neat!
Re: Show HN: Fuse – statically typed functional programming language
#43Can I write a game using OpenGL in this language? Does its functional purity allow this?
Re: Show HN: Fuse – statically typed functional programming language
#44Earlier quoted context omitted.
`Self` isn't the applied type (`List[A]`), rather it's the type constructor of kind `* -> *` constrained by `Functor`. In the map example it gets desugared into: fun map[Self: Functor, A, B](self: Self[A], f: A -> B) -> Self[B]; Since `Self` is the unapplied constructor, `Self[B]` just means `Functor[B]` e.g. `List[B]` not `List[A][B]`. The example you've shown with `SizedFunctor` is not currently supported, as suppo…
Right, I got the notion — but syntactically I expect `Self` to refer to the thing named at the top of the block, which is a `Functor[A]`. I think what both I and the sibling comment are getting at is that there is a difference between `Functor : (Self : * → *) → Class` and `Functor : (Self : * → *) → (A : *) → Class`/preapplied `Functor : (Self : *) → Class` and the syntax seems to merge the two (using syntax for the…
You would want for type variable to not be attached directly to a type class on its definition? But still treated as a container type. Something like:
trait Functor:
fun fmap[A, B](f: A -> B, c: Self[A]) -> Self[B];
...
impl Functor for List[A]:
fun fmap[A, B](f: A -> B, l: List[A]) -> List[B]
List::fold(l, Nil[B], (t, h) => Cons(f(h), t))
...
The above would compile, but the Functor wouldn't be treated of a higher kind in the type-system. I'll try to work a flexible solution, thanks for the great callout!Re: Show HN: Fuse – statically typed functional programming language
#45Earlier quoted context omitted.
Luau is statically typed and interpreted/JIT'd: https://luau.org/
Oh, nice, I didn't know - I always thought that Luau has only type annotations and is not statically typed per se. But yeah, looked into the documentation and you can set !strict mode per script, which will cause interpreter to assert the types. Looks promising. Can you tell me how well it works in practice?
You may be interested in https://lute.luau.org/, which is a node.js-style runtime for the language.
Re: Show HN: Fuse – statically typed functional programming language
#46Nice to see a pretty advanced language at frontpage of HN! From what I understand, GRIN does some parts of supercompilation [1] during optimization process. Supercompilation can prove equivalence of functional programs [2] modulo termination. So you can have something interesting and useful in almost no time. ;) [1] https://themonadreader.wordpress.com/wp-content/uploads/2014/04/super-final.pdf [2] https://www.resear…
> It appears that Fuse does not have user-defined operators. Am I right?
Not yet, but I left this mechanism completely open. As operators are defined as type classes with their signs as method definitions.
[1] http://nbviewer.jupyter.org/github/grin-compiler/grin/blob/master/papers/The%20GRIN%20Project.pdfRe: Show HN: Fuse – statically typed functional programming language
#47Off topic: what is the most convenient statically typed language that don't require compilation/transpilation? To run instead of bash or Python, but types are mandatory (not just hints like python). I know jShell has been here like 10 years, but I'm not sure it's convenient to quickly write to a file, query a url, etc. .ksh for Kotlin? Typescript (through Deno)? Lua?
Re: Show HN: Fuse – statically typed functional programming language
#48Earlier quoted context omitted.
Right, I got the notion — but syntactically I expect `Self` to refer to the thing named at the top of the block, which is a `Functor[A]`. I think what both I and the sibling comment are getting at is that there is a difference between `Functor : (Self : * → *) → Class` and `Functor : (Self : * → *) → (A : *) → Class`/preapplied `Functor : (Self : *) → Class` and the syntax seems to merge the two (using syntax for the…
Fair point, I don't disagree with the statement that `Self` can be limiting as the trait is defined for `Functor[A]`. Thus imposing limitations on type system. You would want for type variable to not be attached directly to a type class on its definition? But still treated as a container type. Something like: trait Functor: fun fmap[A, B](f: A -> B, c: Self[A]) -> Self[B]; ... impl Functor for List[A]: fun fmap[A, B]…
† There's an encoding of higher-kinded types in some languages that don't really have them as first-class citizens (e.g. Rust with associated type constructors) that does this by adding a ‘rewrap’ item to the trait: you implement `Functor` for `List`, but also (as part of the trait) includes a type constructor `Rewrap = List`. This lets you encode the fact that the `Functor` instance is defined for `List` for all values of `A`, but you still struggle to prove that some of their items are independent of the choice of `A`.
‡ To see both of these side-by-side, consider the instance for pairs, which are functorial in their right parameter (as well as the left parameter: they are bifunctorial, but that's not relevant here). So if you have a curried pair type constructor `Pair : * → * → *` it really is true that `Pair[A]`, not `Pair`, is a `Functor`:
impl Functor for Pair[A]:
fun fmap[B, C](f: B -> C, self: Pair[A][B]) -> Pair[B][C]):
Pair(self.0, f(self.1))