Open meisl opened 11 years ago
There are some more that need to be defined but which I don't need for #5. Also, I can't give substantial suggestions for them yet. I'll name them later, with comments about what they ought to refer to and partly some first rationale.
Hmm, maybe put each definition in a separate comment? This way they could be referred to from elsewhere and a link be provided, s.t. you could click on eg " _OLA_ " and be taken to " _object-level assertion_ ". ?
Good initiative. I haven't had time to give your suggestions the thought they deserve so I refrain from commenting on them now. I did set up an wiki page here where we can collect the definitions. For now I think definitions that are not disputed are definitions until they are disputed. Basically, we can consider your suggestion a good starting state.
I have been using combinators quite sloppily. I think that there are both combinators
and combineable
asserts. ( higher level asserts that can combine other combineable asserts), all combinators are combineable but all combineables are not combinators.
In grammars we talk about terminals and non terminals which in are equivalent to what I mean with combineable and combinator.
I will have to read up on parser combinator terminology. I'm thinking that for combinable asserts it should be a good starting point.
About meta asserts - with the changes I'm working on they would pretty much be assertions about promises. What I think is the interesting part is test case generation for asserts in the test-helper ways. I have always seen them as utilities for expressing facts about asserts, not as asserts (each fact will be represented as a test and your work takes away a lot of grunt work as well as gives a reasonable template for describing the asserts.
That's it for now. I hope to be able to get my branch a bit further towards integrating the promise based raw asserts into referee.
Thanks, the wiki is a good idea, just the right place! (btw, the link you gave has a surplus "issues/" in it, hence not working)
I have been using combinators quite sloppily. I think that there are both 'combinators' and 'combineable' asserts. ( higher level asserts that can combine other combineable asserts), all combinators are combineable but all combineables are not combinators.
Yes, that should be roughly the notion of my equally sloppily using "'real' combinators" vs "not real/not-necessarily 'real' combinators". However, for a workable definition we still have to tweak it a bit. For example, "all x are y but all y are not x" isn't really fortunate, IMHO. As a matter of fact, it leaves me in doubt whether you meant "...but not every y need be an x" or rather "...but no y is an x (ever!)" ;) But anyways, that's not urgent. Btw: we haven't even defined "assertion" in the first place...(!) Yet again: just to say. No problem for me so far :)
In grammars we talk about terminals and non terminals which in are equivalent to what I mean with combineable and combinator.
I like this analogy! Namely for it promotes the basic idea: atoms (~> terminals), ie something you cannot view as made up from (smaller) parts vs compound things (~> non-terminals). "...you cannot view as..." is of course a matter of perspective that we can (and must, and will) decide on. Then, what is/are the operation/s to build up compound things? Answering these questions for our domain will lead to a thorough definition (and most probably more). So that's why it's a good analogy, it triggers the right questions.
I will have to read up on parser combinator terminology. I'm thinking that for combinable asserts it should be a good starting point.
Definitely, it's been a source of lots of inspiration already. As long as we don't identify parsers with assertions (of whatever kind) it's all fine. The relation is again analogical. That is, on the surface - I'm almost sure that there is a more profound concept (ie one concept) underlying both. That's why I'm always bringing up monads ...without understanding enough :( Nevertheless, analogies are a Good ThingTM! For me, personally, "analogical thinking" is actually where the cool ideas are coming from. Must be balanced / interleaved with "analytical thinking" of course. So getting this balance right is what makes the art, IMHO.
About meta asserts - with the changes I'm working on they would pretty much be assertions about promises. [...] I have always seen them as utilities for expressing facts about asserts, not as asserts [...] your work takes away a lot of grunt work [...]
Well, I'm basically trying to raise the level of abstraction (and see how far I can push it). So particularly this:
...as utilities for expressing facts about asserts, not as asserts
...I am taking as a challenge, saying "why not express facts about asserts - by asserts!?" After all, asserts are there for expressing facts about something... However, as for any abstract construct - and if possible at all - it must be built from lower-level building blocks[1]. Raw asserts is one. My hack re intercepting buster's fail is another one, albeit ugly, hacky, and "not bearing much weight". But note: not every thinkable building block necessarily needs to be used!
_Promise based_ raw asserts, in comparison, almost seem like a _silver-bullet building block_ to me, so :D ...
-- [1] In the end it's all nothing but a dumb (finite! deterministic!) Turing machine. Or λ. Or CL ;)
How about primitive asserts for terminals and assert combinator for nonterminals. It is in line with how they describe parsers here
+1 for primitive assert vs combinator!
+2 for the paper by Hutton + Meijer :) Haven't read through it yet but seems to include - and be way more comprehensive than - the 1992 one (4 yrs earlier) by Hutton alone, which I had mentioned elsewhere. Right?
A condensed version of 8 pages from 1998, by the same two authors: Monadic Parsing in Haskell
This paper is a tutorial on defining recursive descent parsers in Haskell. In the spirit of one-stop shopping, the paper combines material from three areas into a single source. [...] The paper is targeted at the level of a good undergraduate student who is familiar with Haskell, and has completed a grammars and parsing course. Some knowledge of functional parsers would be useful, but no experience with monads is assumed.
looking good
I'd like to propose some definitions so we can discuss things in a more concise way (and hopefully get things clear faster). I've felt a need for this quite for a time and now that I started to tackle #5 finally found myself unable to go without.
Plz note that this is a proposal, a request for comments. We can change anything anytime (but not too often, plz).
_meta_ assertion
That's what I'm aiming to make in #5; most and before all others:
fails
. I'm calling them "meta" because they are assertions about assertions.Ex: consider the "⇔" vs the "↔" in
"⇔" is a meta symbol while "↔" is not. Yet both read - and mean - "if and only if". The difference is that ↔ is about predicates on numbers while ⇔ is about propositions on predicates on numbers. Other meta assertions might be
passes
,throws
/yieldsError
,failsWithMessage
, whatever. I'm going forfails
first._higher-order_ assertion
Most general: any assertion that takes other assertions as argument (and possibly other things) and/or produces an assertion, very much like "higher-order functions".
So any meta assertion is also higher-order but not necessarily vice versa. Ex.:
or
,and
,some
,all
are higher-order BUT NOT meta whereasfails
is higher-order AND meta._object-level_ assertion (OLA/
ola
)The assertion that a meta assertion is about; standard variable name for such is
ola
.Ex:
assert.fails(assert.equals, [2, 3])
would read "assert thatassert.equals(2, 3)
fails" and have object-level assertionequals
& meta assertionfails
. An OLA can be higher-order, as inassert.fails(assert.all(numbers, assert.isEven))
, whereassert.all
,assert.isEven
and the result ofassert.all(numbers, assert.isEven)
are OLAs but notassert.fails
.assert.isEven
is the only one that's strictly non-higher-order andassert.fails
is the only meta assertion.assertion _definition_ (
isXyzDef
, ie suffixDef
)The
thing
inreferee.add(name, thing)
.Ex:
assertion _implementation_
The
assert
function of an assertion definition.Ex: the
fn
inreferee.add(name, { assert: fn, ... )
, or:function under test (FUT,
fut
)Should be clear;
fut
as variable name.You might have wondered why there is no
ma
convention for "meta assertion" variables. Well, I just haven't come across a need for it yet. Consider: the meta assertions themselves need to be tested, of course. But how would that look like? Maybe this (which should pass)refute.fails(assert.fails(assert.equals, [2,3]))
? Well, that's a bit circular. We cannot (reasonably) usefails
to test itself. So more reasonable isassert.isTrue(failsDef.assert(assert.equals, [2,3]))
, wherefailsDef.assert
is NOT an assertion, just a function. Hence...