Firth
Firth copied to clipboard
Type declarations
These are hard to do and I'd prefer not to have special syntax for them (though something like [Int Int] list. [Int] list. fntype.
is a bit cumbersome?). They'll probably copy Cat's system since it's brilliant.
We should have Haskell-style typeclasses in order to be able to implement operators properly.
Maybe def
could have support for typechecking?
/sum [ Int Int ] [ add. ] def.
1 1 sum.
'Hello' 1 sum. ; This would fail
As for typeclasses, we can probably reuse get
to get properties of a type?
/length 'Hello' get.
Just a thought.
That's basically the idea. Some way of annotating functions with types, perhaps like so:
/sq [int] list. [int] list. fn. [
dup. mul.
] hint. def.
There are two main problems:
- It must not be too verbose.
[int] list. [int] list. fn.
is very long for what could simply beint -> int
- It must be able to express more complex types of things. One example is the type of
if
, which is'A bool ('A -> 'B) -> 'B
in the notation Cat uses (which I borrowed for the spec). I'm not sure how to express that using Firth syntax... if it followed that[int] list. [int] list. fn.
example it'd be way too long and not very nice to read.
To reduce the verbosity a bit, you could drop the list.
bit, reducing it down to just [int] [int] fn.
- but I'm not sure if making those arguments implicitly converted to lists is a good idea. Hmm.
If we do have the argument implicitly be lists, it looks quite good:
/sq [int] [int] fn. [
dup. mul.
] hint. def.
hint
here would just be a function that takes some value and a type signature, and annotates (hints) that value with the type signature. Name could possibly be improved. It'd be both checking that the value matches the type given (str 1 type.
would be an error), and if the value is a function, checking at runtime that it returns the right values. Eventually, with a smart compiler supporting type inference, some type checking could be done at compile-time, too.
So I guess that could work. But it still doesn't solve the type variables/vectors issue, which you need to describe if
and such.
What would fn.
do?
fn
would be a type constructor. fn
on its own is not a type, it's incomplete without argument information. So [int] [int] fn.
calls fn
and it produces a type value representing a function taking an integer and producing an integer. Or something like that, I think.
Wouldn't hint
do something like that? Calling fn
and hint
is kind of verbose imo.
Having an fn
function would be useful if type signatures could be also used in other places.
Well, eventually you'd have some form of reflection to find the type of a value.
With hint
, you might not just be using functions. Though that's certainly the main use case, I think.
Ah cool! So you'd be able to do [int] fn. 5 hint.
as well?
No, that'd just be int 5 hint.
since int
is the type of 5
[int] [int] fn.
(like int -> int
in the spec) is the type of, say, [ 1 add. ]
A function taking nothing and producing an integer would be [] [int] fn.
, e.g. [12]
[int] [int] fn. 5 something-that-returns-an-int hint.
is it now correct?
Almost, except it'd need to take an integer as well, and there's that lingering 5
.
But editing your comment means my comment doesn't make sense, it'd be better to just reply.
Well, something-that-returns-an-int
would take an integer, like specified in the typehint, in that case, that is 5
and return a new int. The hint should be correct?
That 5
is out of place, you've passed it to hint
where it expects a value.
Oh, yeah. I understand. Will types like int
be capitalized as Int
like in the spec? Won't that be out of place?
They were capitalised, but the language doesn't actually allow capitalised identifiers any more, so they'll be lowercase.
fn
returns a type signature, would that be a new type then?
There's a type for types, type
.
fn
would be what you'd call a parameterised type in Haskell or a generic type in Java or C#. It's not complete without its parameters. In Firth fn
itself is just a function taking two functions and producing a type, so (-> 'A) (-> 'B) -> type
.
Oh, I didn't know there is a type for types already, heh. :)
We can probably also add casting, int '5' cast.
Some form of casting would be necessary. But you'd need a function for each type, since each has its own requirements. A catch-all cast
function probably won't work well.