Your approach is interesting and powerful. It would be a lot more work for
each type. Also, an issue with comment based annotations is that comments can
easily become lies, when you update the code without updating the comment.
To do add in my system
add =: +&('num'&cV) NB. coerceable version (applies to both inputs)
'3' add ' 4 5'
7 8
the next release will have a shaddowing t adverb that can be globally switched
from coercion to validation. And so globally allow changing add between
previous and next definition
add =: +&('num'&vV) NB. validation version (applies to both inputs)
'3' add ' 4 5'
|Must be numeric: vV
| ]x v y
Its also possible to annotate the return value
3 (4 : '''not num''')&('num'&cV) 2 NB. function that returns static text
not num
3 ( 'num' vV (4 : '''not num''')&('num'&cV)) 2 NB. return value enforced
numeric
|Must be numeric: vV NB. error due to failed return validation
| ]x v y
add can be defined with return validation (hard to fail so only benefit is doc
completeness) as
add =: 'num' vV +&('num'&cV)
Another interesting toy version that pollutes the screen with smoutput or
"warnings" (log) file every time a coercion is performed, is a nice middle
ground between hard (breaking) validation and completely silent type coercion.
----- Original Message -----
From: Joe Bogner <[email protected]>
To: [email protected]
Cc:
Sent: Monday, January 26, 2015 11:11 PM
Subject: Re: [Jprogramming] I've made a type system for J
Thanks Pascal.
This also made me think of static typing. I have had found static
typing to be useful in other languages. I like your idea of optional
typing too. It reminds me of typescript. It could be nice to be able
to annotate J functions with optional typing. It could then be caught
at 'compile' time instead of run time. I won't get into the dynamic vs
static typing advantages and disadvantages as that's more for the chat
forum. I have had instances in other languages where I've changed a
function signature and not realized I had some other usage of it even
after doing a code search for it.
Here's a crude prototype that I started to knock together for optional
static typing annotation. I suspect something like this is not a good
idea, but I enjoyed playing with it as a toy
In this prototype, you would define your J code as a string within a 0
: 0 block. The ending parentheses would need to be escaped. In this
case I'm using double end parentheses.
code =: 0 : 0
NB. add (num) : (num) -> num
add =: +
NB. twoXArgs (num, lit) : (num[]) -> num[]
twoXArgs =: 4 : 0
'factor f'=. x
factor +`*@.('+*' i. f) y
))
test =: 3 : 0
a=. (2;'+') twoXArgs i.5
))
1 add 2
test''
)
compile =: 3 : 0
defnsrx=: 'NB. [[:alpha:]]*\s?\(.+\)\s\->\s?[[:alpha:]\[\]]+' rxall code
defns=: ([: ;: 4&}.&]) each defnsrx
for_d. defns do.
func=.(0{::>d)
matches=.(((<func) e. }.@:]) every # ]) words
for_m. matches do.
smoutput 'comparing'
smoutput ;d
smoutput 'to'
smoutput ;m
end.
end.
0!:100 ('))';')') stringreplace y
NB. words=. (;: each LF cut code)
)
It doesn't do anything other than look for matches between the
annotation and the actual code. Code would need to be written to
compare the usage to the type annotation, but it might be useful as a
way of communicating the intent
compile code
comparing
┌───┬─┬───┬─┬─┬─┬───┬─┬─┬─┬───┐
│add│(│num│)│:│(│num│)│-│>│num│
└───┴─┴───┴─┴─┴─┴───┴─┴─┴─┴───┘
to
┌─┬───┬─┐
│1│add│2│
└─┴───┴─┘
comparing
┌────────┬─┬───┬─┬───┬─┬─┬─┬───┬─┬─┬─┬─┬─┬───┬─┬─┐
│twoXArgs│(│num│,│lit│)│:│(│num│[│]│)│-│>│num│[│]│
└────────┴─┴───┴─┴───┴─┴─┴─┴───┴─┴─┴─┴─┴─┴───┴─┴─┘
to
┌─┬──┬─┬─┬─┬───┬─┬────────┬──┬─┐
│a│=.│(│2│;│'+'│)│twoXArgs│i.│5│
└─┴──┴─┴─┴─┴───┴─┴────────┴──┴─┘
On Mon, Jan 26, 2015 at 6:31 PM, 'Pascal Jasmin' via Programming
<[email protected]> wrote:
> The hypothetical inCelcius converter scenario assumes that you have had the
> misfortune of scraping different web sites for data where you are promised
> that it will be easy because everyone uses clean structure ways of presenting
> their data. So, it assumes that you have gotten data some of it already
> numeric, some in various string formats. That assumption is why I used
> SCRAPEDATA as the test noun. Temperature may be a bit artificial, but if
> there were web records of Canadian temperatures that went back far enough,
> some would be in F before changing over to F.
>
> To answer your isFreezingC application,
>
>
> 0&>: 'inCelcius' c_temperature_ every 44 ;'99F';'7K'; ' _20 Faren.'; '300
> Kel.'
> 0 0 1 1 0
>
> for Farenheit, you can either use:
>
>
> isFreezingF 'inFaren' c_temperature_ every 44 ;'99F';'7K'; ' _20
> Faren.'; '300 Kel.'0 0 1 1 0
> isFreezingF 'inCelcius inFaren2' c_temperature_ every 44 ;'99F';'7K'; ' _20
> Faren.'; '300 Kel.'
> 0 0 1 1 0
>
>
> the latter could also be written 'inCelcius inFaren' but as written is more
> efficient because inFaren2 already assumes that it has numbers that were
> guaranteed by inCelcius. Its definition is also much simpler than inFaren
> because the latter needs to deal with potential strings and various source
> formats.
>
> I think too that 'inCelcius inFaren' is better documenting because it
> explains that the function uses Fahrenheit but accepts/expects Celcius
> Also:
>
> data #~ isFreezingF 'inFaren' c_temperature_ every data =. 44
> ;'99F';'7K'; ' _20 Faren.'; '300 Kel.'┌──┬───────────┐
> │7K│ _20 Faren.│
> └──┴───────────┘
>
>
>
>
> ----- Original Message -----
> From: Joe Bogner <[email protected]>
> To: [email protected]
> Cc:
> Sent: Monday, January 26, 2015 5:53 PM
> Subject: Re: [Jprogramming] I've made a type system for J
>
> I also looked through it and became confused. I think I will need to run
> the tests or wait for more documentation.
>
> It sounds like the example given solves the problem of detecting
> incompatibilities in values or make the values comparable.
>
> In this example it is a list of temperature values which are in different
> units. We want to validate the user is supplying data in the right unit or
> we want to convert the data supplied to equivalent units.
>
> I can think of some toy examples like
>
> isFreezing =: 32&>:
>
> This will clearly give the user the wrong answer if celsius is passed in
>
> We could define
>
> isFreezingF =: 32&>:
> isFreezingC =: 0&>:
>
> Then we would need to know which to call in what circumstance
>
> It would be better to be able to have a function that could try and produce
> the right result depending on what the user supplied or produce an error if
> not
>
> An explicit way may be to do this:
>
> isFreezing =: 3 : 0
> unit=. {: y
> temp=. ". }: y
> if. unit = 'F' do.
> temp <: 32
> elseif. unit = 'C' do.
> temp <: 0
> elseif. do. _1
> end.
> )
>
> isFreezing every ('32F';'1C';'0C';'5K')
>
> Or we could do something like this
>
> isFreezingF =: 32&>:
> isFreezingC =: 0&>:
> isFreezingUNK =: _1:
>
> isFreezing2 =: 3 : 0
> unit=. {: y
> temp=. ". }: y
> (isFreezingF`isFreezingC`isFreezingUNK@.('FC' i. unit)) temp
> )
>
> isFreezing2 every ('32F';'1C';'0C';'5K')
>
>
> You can imagine this could get unwieldy if we wanted to add isBoiling or
> isHot, isCold or is isWarmerThan ....
>
> In these cases the coercion would be nice to get back to a single base unit.
>
> Now I need to play with your type system to see how it would help with this
> problem
>
> On Mon, Jan 26, 2015 at 5:04 PM, Raul Miller <[email protected]> wrote:
>
>> I took a quick look at it.
>>
>> I do not think lassign is very meaningful. I can think of uses for it,
>> but they seem obscure.
>>
>> Meanwhile, I am also not clear on the difference between 'in' and
>> 'of'. (They behave the same on my simple tests, and there's a lot of
>> code to wade through, here.
>>
>> I don't suppose you feel like putting together a ref doc (for example:
>> one sentence descriptions on the important words, along with
>> representative sample data)? The test scripts look promising, though,
>> so maybe I'll discover what I need there...
>>
>> Thanks,
>>
>> --
>> Raul
>>
>> On Mon, Jan 26, 2015 at 3:36 PM, 'Pascal Jasmin' via Programming
>> <[email protected]> wrote:
>> > https://github.com/Pascal-J/type-system-j
>> >
>> >
>> > This is actually the type system I'd like any language to have. Its
>> much cleaner than class-based user defined types in that you don't need to
>> define casting function into and out of classes.
>> >
>> > This may be a bit hard for beginners in that to fully use with explicit
>> multiline code, the user needs to understand how 3 : 0 can be part of a
>> fuller line. But its both powerful to create types, and easy enough for me
>> to consume them.
>> >
>> > Some unique powerful features are compound types, parameterized types,
>> and inputwide (record/array vs field) validation (type)s.
>> > ----------------------------------------------------------------------
>> > For information about J forums see http://www.jsoftware.com/forums.htm
>
>> ----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm
>>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm