DRAT!  What (genius negated) designed gmail's interface?

If I am wrong that the canHandleInput: class method of
IllegalMoveSanta should return false, not true (because
the order of the elements of #subclasses is not defined,
so that IllegalMoveSanta might *always* be selected),
then that is further evidence that avoiding "if" made
the code LESS readable.

You are a beginner at this, doing all the right things
for a beginner to do.  One of the things you have to do
is to develop a sense of "smell" for code.  Each class
ought to "pull its weight".  Four classes -- which it
really does not make sense to instantiate, just put the
instance methods on the class side and drop the #new --
just to avoid a couple of very clear "ifs"?  I don't
think so.  IF THESE CLASSES NEEDED TO EXIST FOR SOME
OTHER REASON, if they had real work to do, sure.  But
they don't.  They only bloat and obscure the code.



On Wed, 28 Nov 2018 at 20:54, Richard O'Keefe <rao...@gmail.com> wrote:

> In Advent-of-Code 2015, the first problem is
> really quite simple.  There are at least two
> ways to think about it.
> "CS101":
>    set a counter to 0
>    for each character of the string
>      if it is '(' increment the counter
>      if it is ')' decrement the counter
>    report the counter
>
> "Higher level":
>    report the difference between
>      (the number of '(' characters in the string) and
>      (the number of ')' characters in the string).
>
> Expressed in Smalltalk this looks something like
>   Transcript print:
>     (s occurrencesOf: $() - (s occurrencesOf: $)); cr.
>
> Make no mistake: you *cannot* tell the difference
> between $( and $) using class-based dispatch because
> they belong to the same class.  There has to be an
> "if" somewhere, the question is not whether but where.
> In this case, counting the number of occurrences of an
> object in a collection is has been a standard Collection
> method for nearly 40 years; it's one of the basic
> operations you need to learn.
>
> The "higher level" approach can be less efficient that
> the "CS101" approach, but in a case like this we really
> do not care.  We want the code to be *clear*.
>
> What about the second part of the problem?
> Not having submitted any answers, I can't actually
> see the second part on the AOC site, but luckily you
> have included it in your program.
>
> We want to
>    [find the first place] where
>       [the cumulative sum] of (c=$()
>       [minus]
>       [the cumulative sum] of (c=$))
>       equals -1.
>
> The "CS101" approach is
>    n := i := 0.
>    while n >= 0 and i < size(s) do
>       i +:= 1
>       if s[i] = $( then n := n + 1
>       if s[i] = $) then n := n - 1
>    report n
>
> The "higher level" approach looks something like
>   n := (s cumCount: [:each | each = $(]) -
>        (s cumCount: [:each | each = $)])
>        indexOf: -1.
> -- although it gives 0 instead of s size + 1 when
> -1 is never reached.
>
> Here #indexOf: is standard, #- is defined on sequences
> in Squeak and Pharo, but #cumCount: does not
> exist.  So we need something like
>
>     cumCount: aBlock
>       |c a|
>       a := Array new: self size.
>       c := 0.
>       self withIndexDo: [:each :i |
>         (aBlock value: each) ifTrue: [c := c + 1].
>         a at: i put: c].
>       ^a
> This is *not* coupled to the particular use we have
> in mind for it; it is in no way tied to characters
> or strings.  It's quite general.
>
> Note: we do not need any new classes, except maybe
> a place to put one problem-specific method.
>
> While this answer, with no loop and no if in the
> problem-specific code, is quite pretty, it has a
> problem.  Suppose the string to have M characters
> and the desired step to be number K.  The CS101
> approach takes O(K) time and no allocations, but
> the higher level approach takes O(M) time and
> allocates three M-element Arrays.  (In a non-strict
> functional language like Haskell, the higher level
> version *also* takes O(K) time, and with a good
> enough "deforesting" compiler should allocate no
> data structures.)
>
> For a problem like this, I really don't care about
> the efficiency aspect.  If I *do* care about that,
> then starting from a higher level version gives me
> something to test a lower level version against.
>
> To get an efficient answer to the second part,
> we still don't need a new semantic class, just
> some place to put the code.
>
> Day1
>   class methods:
>     indexOfFirstBasementTime: steps
>       |floor|
>       floor := 0.
>       steps keysAndValuesDo: [:i :each |
>         each = $( ifTrue: [floor := floor + 1].
>         each = $) ifTrue: [floor := floor - 1].
>         floor = -1 ifTrue: [^i]].
>       ^0 "same convention as #indexOf:"
>
> Does this contain "if"?  Why yes, it does.
> Is there any problem with that?  Why no, there isn't.
> You need to treat members of the same class (left
> parenthesis, right parenthesis, others) differently.
> You need to treat members of the same class (minus
> one, all other integers) differently.
> Would there be any gain in clarity or maintainability
> if these ifs were somehow eliminated?  Certainly NOT.
>
> Quite the reverse, in fact.
> input2 withIndexDo: [ :element :index | |action|
> action:= SantaAction getActionFor: element. floor := action
> doMovementFor: floor .
> self hasReachedBasement
> ifTrue: [^ index]].
>     ^ '-2'.
>
> There is only one word for this: obfuscated.
> I was initially puzzled by your returning -2
> instead of the conventional 0 if the basement
> is not reached, and then *deeply confused* by
> the fact that you are returning a *string* in
> this case.
>
> Looking at your code, I was further confused
> by variables called 'aSymbol' whose value is
> always and only a Character, never a Symbol.
> And if I am wrong that
> IllegalMoveSanta class>> canHandleInput:
> in Smalltalk is to return 0 when something is
>
> approach
>
>
>
> We want to find the first place where something
> becomes true.  There are again at least to approaches.
>
> On Wed, 28 Nov 2018 at 05:41, Roelof Wobben <r.wob...@home.nl> wrote:
>
>> Hello,
>>
>> Yesterday I had a talk with luc frabresse about using if then.
>> He said if I understand it right, Its the best to not using a if then or
>> a ifTrue/ifFalse.
>>
>> Can anyone help me figure out how to rewrite this project so I will not
>> use the ifTrue in the basement function.
>>
>> my code so far can be found here :
>> https://github.com/RoelofWobben/AOC2015
>>
>> Roelof
>>
>>
>>

Reply via email to