Open Skalman opened 11 years ago
The this
context not currently covered - great catch! Languages like Python consider it the same as a parameter - @kurttheviking, have you seen this case covered well in python, for example?
I'm not very satisfied with either 1 or 2 that you propose. In 1, it distracts from the position in the parameter list, which is actually quite significant. 2 makes is less clear for named function signatures, eg:
String.prototype.toLowerCase (String) => String
A few things come to mind: a # is often used in ad hoc notations to refer to an instance method. Without making assumptions about any particular constructor, some variant might be used to describe the expected this
value:
ArrayLike#join( separator?: String ) => String
ArrayLike is hard to specify generically, but it is a common enough case in both ES5 and popular APIs (like the DOM) that it might be good to include it in the jsig spec itself. Again, consider that the aim of jsig is to facilitate communication with other programmers. Without seeing a formal definition, but being familiar with JavaScript, would seeing the term ArrayLike
be ambiguous to you?
I was thinking about characters to use, but didn't think of #
. To me your version looks good.
The term ArrayLike
is indeed quite clear, but it would be really nice if jsig were parsable. The main goal should be readability for humans, but it would be a pity if it were impossible to create tooling around this.
I agree that ArrayLike
type should be in the spec. But I don't like magic that I can't reproduce, so I think there should be a way to define something like ArrayLike
.
TypeName: BaseType where { JS expression }
TypeName: BaseType where { JS code that returns something }
This would also allow for something like // Char: String where { obj.length === 1 }
If we take constraints, I like the idea of using plain JavaScript expressions - but in this case where is obj
coming from in obj.length
? Is that a keyword used by convention to refer to the object under constraint?
For any function that relies on this
I've made it obvious that it's a method that relies on this
and then have just treated it as the first parameter to a function. For example ( https://github.com/Raynos/immutable-hash#hashgetkey )
@jden Yeah, obj
is just the "in parameter". Would something like val
or instance
be better? Any ideas?
@Raynos I think that jden's suggested Type#
is clearer than Type ->
.
I'm reluctant to introduce Haskell style typing. I personally quite like it, and it seems very elegant to me. But it hasn't helped me when trying to communicate with non-Haskell people. As much as possible, I'd like to try to stick to JavaScript itself for syntax precedent (or ES6, which has already hashed out a lot of the conversations around evolving the language syntax in a way that will fit in nicely with existing code). Also, in JavaScript, currying is not the default behavior, so expressing N-ary functions as A -> B -> C
rather than (A, B) => C
doesn't play nicely with the mental model of how functions in JavaScript are executed.
I've made it obvious that it's a method that relies on
this
In this example (https://github.com/Raynos/immutable-hash#hashdiffotherhash), you're showing it as parameter named this
, which is in line with @Skalman's suggestion above. Expressing it as a first parameter is also similar to how Function#bind
, Function#call
, and Function#apply
take arguments.
A special parameter name this: // (this: ArrayLike, separator?: String ) => String (might be too magic)
I've implemented this in my Parser ( https://github.com/Raynos/jsig/blob/master/test/parser/functions.js#L101 ).
This approach is encoding that this
is just another argument to a function and that if you dont explicitly define this
as the first argument then your function doesn't use this
.
This implementation is nice because it means there is no extra syntax to express this
it's just a function argument label that is interpreted specially, just like how we deal with optional parameters foo : (bar?: T) => void
or rest parameters foo : (...bar: X) => void
Feel free to close if this addresses your concerns.
I like this idea. Perhaps we should add a section addressing reserved keyword labels. In most cases it makes sense to prohibit them. In this particular case, having a this
label in a ParameterList, it makes sense to define the behavior as stipulating the type of the this
object in the function scope.
Leaving this open pending clarified text in the readme and or spec.
When calling a function there's an extra parameter that you usually don't think about: the
this
value.The signature for
Array.prototype.join
feels a bit off:// ( separator?: String ) => String
I don't have any really good suggestions for what it should look like. Here are a couple, though:
this
:// (this: ArrayLike, separator?: String ) => String
(might be too magic)// ArrayLike.( separator?: String )
(not very beautiful)Btw, is there a way to specify the type
ArrayLike
with jsig?{length: Number}
only reaches part way there. I can't think of a good solution for that without somehow allowing arbitrary JS validation, like: