intertype
Advanced tools
Comparing version 2.8.0 to 2.9.0
@@ -322,2 +322,6 @@ (function() { | ||
//......................................................................................................... | ||
this.declare('value', function(x) { | ||
return !this.isa.promise(x); | ||
}); | ||
//......................................................................................................... | ||
this.declare('object', { | ||
@@ -324,0 +328,0 @@ tests: (x) => { |
@@ -123,2 +123,6 @@ (function() { | ||
this.check = Multimix.get_keymethod_proxy(this, check); | ||
this.nowait = function(x) { | ||
this.validate.value(x); | ||
return x; | ||
}; | ||
declarations.declare_types.apply(this); | ||
@@ -125,0 +129,0 @@ declarations.declare_checks.apply(this); |
(function() { | ||
'use strict'; | ||
var CND, INTERTYPE, Intertype, alert, assign, badge, debug, demo, echo, flatten, help, info, intersection_of, jr, js_type_of, later, log, njs_path, praise, rpr, test, urge, warn, whisper, xrpr, | ||
modulo = function(a, b) { return (+a % (b = +b) + b) % b; }; | ||
modulo = function(a, b) { return (+a % (b = +b) + b) % b; }, | ||
indexOf = [].indexOf; | ||
@@ -929,2 +930,50 @@ //########################################################################################################### | ||
//----------------------------------------------------------------------------------------------------------- | ||
this["isa.value, nowait"] = function(T, done) { | ||
var error/* ^44452^ */, f/* ^81112^ */, intertype, isa, nowait, r, type_of, types_of, validate, x; | ||
intertype = new Intertype; | ||
({isa, types_of, type_of, validate, nowait} = intertype.export()); | ||
//......................................................................................................... | ||
T.ok(indexOf.call(types_of(new Promise(function() {})), 'value') < 0); | ||
T.ok(indexOf.call(types_of({ | ||
then: function() {} | ||
}), 'value') < 0); | ||
T.ok(indexOf.call(types_of(42), 'value') >= 0); | ||
error = null; | ||
T.eq(isa.value(null), true); | ||
T.eq(isa.value(12.34), true); | ||
T.eq(isa.value(void 0), true); | ||
T.eq(isa.value(new Promise(function() {})), false); | ||
try { | ||
validate.value(x = 42); | ||
T.ok(true); | ||
validate.value(x = void 0); | ||
T.ok(true); | ||
validate.value(x = null); | ||
T.ok(true); | ||
validate.value(x = 1 * '#'); | ||
T.ok(true); | ||
} catch (error1) { | ||
error = error1; | ||
throw error; | ||
} | ||
try { | ||
validate.value(x = new Promise(function() {})); | ||
T.ok(false); | ||
} catch (error1) { | ||
error = error1; | ||
urge("(ok)", CND.red(error.message)); | ||
T.ok(true); | ||
} | ||
if (error == null) { | ||
T.ok(false); | ||
} | ||
f = function(x) { | ||
return x ** 2; | ||
}; | ||
r = nowait(f(5)); | ||
T.eq(r, 25); | ||
return done(); | ||
}; | ||
//########################################################################################################### | ||
@@ -935,2 +984,3 @@ if (module.parent == null) { | ||
// test @[ "isa.value, nowait" ] | ||
// test @[ "types_of() includes happy, sad" ] | ||
@@ -937,0 +987,0 @@ // test @[ "check(): validation with intermediate results (experiment)" ] |
{ | ||
"name": "intertype", | ||
"version": "2.8.0", | ||
"version": "2.9.0", | ||
"description": "A JavaScript typechecker", | ||
@@ -5,0 +5,0 @@ "main": "lib/main.js", |
@@ -17,2 +17,4 @@ | ||
- [Concatenating Checks](#concatenating-checks) | ||
- [Formal Definition of the Type Concept](#formal-definition-of-the-type-concept) | ||
- [`value` and `nowait`](#value-and-nowait) | ||
- [To Do](#to-do) | ||
@@ -204,3 +206,52 @@ | ||
# Formal Definition of the Type Concept | ||
For the purposes of InterType, **a 'type' is reified as (given by, defined by, represented as) a pure, named | ||
function `t = ( x ) -> ...` that accepts exactly one argument `x` and always returns `true` or `false`**. | ||
Then, the set of all `x` that are of type `t` are those where `t x` returns `true`, and the set of all `x` | ||
that are not of type `t` are those where `t x` returns `false`; this two sets will always be disjunct. | ||
Two trivial functions are the set of all members of all types, `any = ( x ) -> true`, and the set of values | ||
(in the loose sense, but see [`value` and `nowait`](#value-and-nowait)) that have no type at all, `none = ( | ||
x ) -> false`; the former set contains anything representable by the VM at all, while the latter is the | ||
empty set (i.e. all values have at least one type, `any`). | ||
# `value` and `nowait` | ||
A maybe surprising type is `value` (in the strict sense), which is a type defined to contain all values `x` | ||
for which `isa.promise x` returns `false` (this includes all native promises and all 'thenables'). | ||
The `value` type has been defined as a convenient way to ensure that a given synchronous function call was | ||
actually synchronous, i.e. did not return a promise; this may be done as | ||
```coffee | ||
validate.value r = my_sync_function 'foo', 'bar', 'baz' | ||
``` | ||
Observe that 'values' in the strict sense do comprise `NaN`, `null`, `undefined`, `false` and anything else | ||
except for promises, so `x?` is distinct from `isa.value x`; therefore, even when `my_sync_function()` | ||
'doesn't return any value' (i.e. returns `undefined`), that is a value in this sense, too. | ||
Equivalently and more succinctly, the validation step can be written with `nowait()`: | ||
```coffee | ||
nowait r = my_sync_function 'foo', 'bar', 'baz' | ||
``` | ||
`nowait x` will always either throw a validation error (when `x` is a promise) or else return `x` itself, | ||
which means that we can write equivalently: | ||
```coffee | ||
r = nowait my_sync_function 'foo', 'bar', 'baz' | ||
``` | ||
At least in languages with optional parentheses like CoffeeScript, this looks exactly parallel to | ||
```coffee | ||
r = await my_async_function 'foo', 'bar', 'baz' | ||
``` | ||
hence the name. | ||
# To Do | ||
@@ -236,5 +287,14 @@ | ||
* [ ] consider whether to return type as intermediate happy value for type checks like `if is_happy ( type = | ||
check.object x ) then ...` | ||
* [ ] implement custom error messages for types and/or hints what context should be provided on failure in | ||
validations, checks; this in an attempt to cut down on the amount of individual error messages one has to | ||
write (ex.: `validate.number 42, { name, foo, bar }` could quote second argument in error messages to | ||
provide contextual values `name`, `foo`, `bar`) | ||
* [X] implement `validate.value x` to check `x` is anything but a promise; also offer as `nowait` method | ||
(the counterpart to `await`) | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
227111
2363
298