-
Notifications
You must be signed in to change notification settings - Fork 0
Deftype #11
base: master
Are you sure you want to change the base?
Conversation
Previously, `rest` was always defined and passed, even if the original call didn't supply enough arguments to reach `rest`. This poses some problems when you expect the length of `arguments` to match that of the original call to the variadic function, so now `rest` is only supplied if there are actual arguments to fill it up with. This means it'll be undefined otherwise, and `arguments` will be identical to the original call. Additionally, I changed `variadic` so that it'll correctly report `length` for the wrapped function, provided the wrapped function `length` is 26 or below. I'd be hard pressed to remember ever seeing a function with more than even 10 parameters, but still. This isn't an ideal solution of course, but probably hits home 99.99% of the time which is enough.
Will return the last value if all values are logically true; or the first logically false value.
Very useful function for getting a property value out of an object. If the object is undefined, will return `notFound` which defaults to `undefined`. If the property doesn't exist on the target object, will return `notFound` as well.
Would return `notFound` even if `map` had `key`, but where the value was logically false.
This is a wrapper around `Object.defineProperties` which makes it easier to add immutable and non-enumerable properties to objects. Just like `Object.defineProperties`, this function will mutate the object in place. It *is* possible to make the properties both mutable and enumerable (but not removable) – however this is by design made to be uncomfortable. Accessor functions or values that are functions will have their scope bound to a private scope, which is an extension of the target object. This allows functions to share data internally, without fear of exposing anything to the outside world. A caveat here is that subsequent calls to `defprop` will create a *different* private scope, with the assumption being that such calls imply that the properties are unrelated. I may want to rethink this at some point.
If the first argument to `when` is logically true, or if the first argument is a function and the result of calling it is logically true, then `when` will return the value of the second argument; otherwise it returns null.
`apply` always returned `undefined`, which seemed a tad wrong. Fixed this and made sure the tests cover that case.
If `val` is called with a function, then any arguments past the first will be passed along to the function.
No idea where the tabs came from.
Well that's nifty tooling, ain't it? |
`is(x, x)` could return false if `x` is an object
It was a bit too magical to make up a magical scope, so now it has to be specified by providing an object. Added global options for all properties as well, making it a bit easier to deal with property options. They can still be overridden for each field however.
Extending objects means creating a new object instance, where the prototype is set to be the base, and the returned instance has the properties of any additional objects passed. If there are multiple objects passed, their properties will be merged with any conflicts resolved by picking the rightmost candidate.
Creates a new object instance, derived from `Object.prototype` and with the merged properties of all passed objects. Property conflicts are resolved by picking the rightmost candidate. Properties are merged by looking at the actual property descriptors and not just values, meaning things like accessor functions and property metadata such as whether it's enumerable, writable, or configurable, are passed along. Thus a merge is about as identical to the input objects as it can get.
This makes it easy to filter properties from the description. Also, this change makes the output consistent, whereas before it would exclude the property name if it was given to the function. This is awkward when using things like `seq` to loop over descriptions.
`describe` now returns an array of arrays, where each array is a key/value pair. I considered flattening this, but figured that might be tricky to deal with. Might revisit later.
I find partial application from the left or right isn't enough to cover all cases, and puts a bit of an unfair burden on function definitions to consider such applications. So I added a think to `partial` where if you set one of the arguments of a partial application to be the `partial` function itself, that acts as a signal to `partial` to say that the specific argument hasn't been supplied yet, and should come later when applying the function. Is-a very nice.
Design note: do not implement internal mutable state for methods and get/set accessors. This is too much of a foot-gun to be useful, and instead any mutability should probably be opt-in and encapsulated on a field-by-field basis; i.e. mutable fields get their own internal state, separate an unreachable from all other fields (unless the field explicitly returns Methods and get/set accessors should probably be bound to the type instance, but only if that instance is fully immutable – that is, not only are fields immutable, but the object is closed for extensions as well. Otherwise, this is a bit too much rope as well. |
Ditch types in favor of tags. Tags should work somewhat like Clojure's |
Not too happy about this...
Reopening this since there's a ton of useful stuff on the branch. However, ditch |
Type definitions in JavaScript is a mess. This branch is an effort to come up with some sort of semantic typing, where relationships between objects can be defined by leveraging JS's prototypes.
These are not an effort to implement classes.