notes-computer-jasperOldList

old

mb on fn defs let the fn name go on the left, even tho its irregular. mb use colon:

take: 0 _ = [] _ [] = [] n x+xs = x,(n-1) xs take,+

note that the fn name only has to be said once

could let colon mean "reverse the things on both sides of the colon, and if the thing on the right if multiple lines, repeat the thing on the left". in this case,

0 _ take = [] _ [] take = [] n x+xs take = x,(n-1) xs take,+

would also work, as would

init takeAppend : 0 _ = init _ [] = init n x+xs = x,(n-1) xs takeAppend,+

and in a non-fn-defn context:

[10 11] takeAppend : 1 [1 2] == [1 10 11]

which is arguably confusing.

mb it should be

take = 0 _ : [] _ [] : [] n x+xs : x,(n-1) xs take,+

this suggests a nice anonymous fn notation: fn x y : blah

and mb node names should also be delimited by =, rather than

if no inputs, colon not needed: a = 3

but mb roles of = and : should be reversed b/c = is more common and the = key is not chorded:

  fn x y = blah
  take:
    0 _ = []
    _ [] = []
    n x+xs = x,(n-1) xs take,+

in this case let fns defined w/o args just use =: a=0

eh, i dunno. lets leave out the :, it doesn't convey information:

a = 0 fn x y = blah take 0 _ = [] /. convention: two spaces ./ take 0 _ = [] _ [] = [] ...


old (no infix functions anymore):

Infix functions

Some operators, for example +, are infix, which means:

You cannot define new infix functions (except by way of token operators, see below), but you can make any normal function that takes at least two arguments into an infix function by attaching '-'s to each side of it like this:

  2 -f- 3

old:

three use cases:

1) (scripting for self) you are writing a quick-and dirty script or a prototype, one that probably will only be run a few times, and in which misbehavior is not that important. You want to write it quickly. 2) (careful scripting for self) you are writing a quick-and dirty script or a prototype, one that probably will only be run a few times, and in which crashing with an error is not that important, but you don't want it to silently misbehave. You want to write it quickly. 3) (for others to use) you don't want errors or crashes. you don't want it to silently misbehave. you want to be able to debug it easily. You don't mind if it takes awhile to write, you just want it to work.

the best for #1 is probably midxic; it's easy to use, and if there are clashes, this might resolve them the way you want; but if you're unlucky, it'll silently misbehave. the best for #2 is probably midx; it's easy to use, and if there are clashes, it'll tell you. the best for #3 is probably midxrn; if you make use of the renaming tables it provides, it'll work.

if we're in situation #2 or #3 and we use midxic, we have some cases in which there are silent misbehavior, which may be sporadic and hard to debug. In situation #2 we are annoyed and in #3 we are extremely annoyed.

if we're in situation #1 and we use midx, we have some cases in which there are crashes, and either we have to go change it to midxic (in which case we're slightly annoyed that the default wasn't midxic), or we have to do something more complicated (in which case we would have had to anyway). if we're in situation #3 and we use midx, we crash in some cases, and we have to switch to midxrn, in which case we're annoyed that the default wasn't midxrn, which would have reminded us think about the label clashes earlier.

if we're in situation #1 or #2 and we use midxrn, we are too lazy to do anything with the rename tables, so we just ignore them, causing silent misbehavior sometimes. In #1, we would have been no worse off using midx, which wouldn't have worked either, and in #2, we would have preferred midx.

we have some cases in which there are crashes, and either we have to go change it to midxic (in which case we're slightly annoyed that the default wasn't midxic), or we have to do something more complicated (in which case we would have had to anyway). if we're in situation #3 and we use midx, we crash in some cases, and we have to switch to midxrn, in which case we're annoyed that the default wasn't midxrn, which would have reminded us think about the label clashes earlier.



old:

case on "Meters or Feet" and then if it's meters, can you assume it's Red? and then if it's feet, can you case on "Float or Int", and if it's int, assume it's Blue? if it's feet, can you case on "Float or Blue"? well heck, those dont sound so hard. let's provide all of them. we're basically providing the DNF too, i guess. but the inference procedure seems simpler -- to see if some case statement covers all of the conditions (remember that each case may only be a simple conjunction), you just have to

no: take the expression of what is known about the type, replace each atom with a bit vector with one place for each atom that occurs in the case statement, and a 1 in the appropriate place if that atom is one of those, otherwise 0s, and then propagate that bit vector up, taking the bitwise max at each AND node and the bitwise min at each OR node. At the top,

no: iterate over each case, and then walk the tree of the expression of what is known about the type, starting from the top. at AND nodes,

no, actually, i think providing all that is NP-complete. For each path in the expression of what is known, you must separately consider if the AND of all of the things along that path satisfies any of the ORs in the cases. Anyhow, the expressions in the cases don't have to be simple conjunctions after all, b/c they can include types.

in fact, here's the reduction to SAT: we want to know if it is possible for the expression of what is known about the type to be true, and at the same time for the case expression to be false. that is, we want to know if the conjunction of (the expression of what is known about the type, and the negation of the case expression) is satisfiable. in this manner, we can construct any CNF boolean expression.

so, how about this. whenever a dijunctive type expression is given, the checker factors out (recursively, if the expression is not simple) any atomic literals which are common to all of the disjuncts. a literal is "atomic" even if it is just a name for a type defined elsewhere. so,

"(Meters and ((Int and Red) or (Float and Red)) and Tall) or (Feet and ((Float and Red) or (Int and Blue)) and Tall)"

becomes

"(Meters and (Red and (Int or Float)) and Tall) or (Feet and ((Float and Red) or (Int and Blue)) and Tall)" (factor out Red from first subexpression)

and then

X = "Tall and ((Red and (Int or Float)) or (Feet and ((Float and Red) or (Int and Blue))))"

you can assume that any of the factored conjuncts are true. you can take cases over anything that syntactically matches the ORs (no, better: anything such that each of the ORs in the above expression is matched by at least one of your cases), except that you only have to match one conjunct in each OR, and that anything that matches the factored conjuncts of the whole thing are removed first. So,

-- old:

  if X is a conjunction, then for each conjunct C in X, search for syntactic matches of C (or weaker; so if C is "A or B", then "A or B or D" matches) in P (including subexpressions of P), and replace them with True (and simplify by removing the Trues, ie. "A and True" -> "A"). (to save time later, you might want to remove atomic conjuncts from X after doing this, assuming you won't expand some named type later and find one of those inside of it). if P becomes True, return Match
  if P is atomic, and wasn't changed to True, return False
  if P is a conjunction, then recursively test each conjunct, and return Match iff they all return Match
  else, P must be a disjunction. return Match if, for any conjunct C of X (C must be a disjunction) (if X is a disjunction, then you have only one C, namely X itself), this returns Match:
       
       test every disjunct Dx in C as follows, and return Match iff they all return Match:
         if Dx is syntactically weaker than P (unnecessary; will be replaced in step 1 of recurse), or some disjunct of P (is that step neccessary? i guess not, for the same reason), return Match
         o/w, recurse, matching Dx against P

(note: if we have a disjunction within a disjunction, or a conjunction within a conjunction, i think we should combine them first? but we don't want to lose information associated with named types. hmmm? but i don't think we lose anything. so we should do this. more realistically, we should not expand atoms until we get to them (or rather, until we get just above them; if we are in an OR, we must expand the atoms now in case they are ORs too, and then for those atoms which turn out to be conjuctions, we can leave them that way, for those that turn out to be ORs, we must expand each of their atomic disjuncts), and we should keep a running list of what has been set to True)