I've made the following updates: neat demos in typesys_test.ijs (easiest to put both files in home dir)
test '' and testC '' run minilab samples. system supports overridable types. Its setup as 2 type categories DYNAMIC and STRICT. It would be pretty straight forward to add more. The command strict 1 will replace in TYPES those items that exist in the STRICT list for the current locale. strict_typesys_ 0 will replace in TYPES those items that exist in the DYNAMIC list for all locales (that have not set their own strict (1) or dynamic (strict 0) type set. I've added some recursively defined types. 'unboxed' is a parameterized type that uses another type as a parameter. Its definition signature is: (parens added for email) unboxed (<@:[ cV every ]) (0 = L.@:]) Must be coerceable to parameter type then unboxed 'num&unboxed' (num as paramter to unboxed type) will apply numeric conversion to every item before unboxing. I've added a super useful coercer variant that smoutputs to screen what it coerced. Its useful for both debugging types, and letting you know unintrusively that your function calls are not getting pure data. I've added a polymorphic shaddow type processor t that can be mapped to any other type processor. It is initially mapped to cp. If you prefer silent coercion can remap to c. Hard validation map to v. It has the same global/locale interactions as strict above. So t_typesys_ =: ... remaps globally. t =: ... remaps "localely" I've added a validator variant that returns a boolean list instead of signalling errors. It automatically checks each item of input seperately and returns an unboxed list of booleans. The name of this type processor is vb. A natural verb parameter is #~ which will select the valid items. Multiple tests are anded together for example. #~ '8<han 2>han' vb 3 1 21 4 5.6 3 4 5.6 if the above input was boxed, then the valid boxed input would be returned. This is also a surprisingly useful variation as it allows a function to filter instead of coerce. Btw here is a neat trick for creating a double adverb. vbs =: 1 : 'u 1 : ''#~ m vb''' this form makes it compatible with t polymorphism, and allows modifying the type interaction of a function with just a change of the processor. +: '8<han 2>han' vbs 3 1 21 4 5.6 6 8 11.2 +: '8<han 2>han' cp 3 1 21 4 5.6 COERCE: 3 1 21 4 5.5999999999999996 COERCE: 3 1 8 4 5.5999999999999996 6 4 16 8 11.2 ----- Original Message ----- From: 'Pascal Jasmin' via Programming <[email protected]> To: "[email protected]" <[email protected]> Cc: Sent: Tuesday, January 27, 2015 1:26 AM Subject: Re: [Jprogramming] I've made a type system for J 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 ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
