Re: [racket-dev] Simple loop checking in beginner?

2010-11-10 Thread Matthias Felleisen

On Nov 10, 2010, at 10:40 AM, namekuseijin wrote:

 On Wed, Nov 10, 2010 at 12:13 AM, John Clements
 cleme...@brinckerhoff.org wrote:
 ;; NOW I'M A STUDENT:
 
 ;; only-long-strings : (listof string) - (listof string)
 ;; return a list containing the strings longer than 2 chars
 (define/noloop (only-long-strings l)
  (cond [(empty? l) empty]
[else (cond [( 2 (string-length (first l)))
 (cons (first l)
   (only-long-strings (rest l)))]
[else (only-long-strings l)])]))
 
 gosh, students do suck.  I guess you teach them to use cond because
 it's a generalized if.  But then they proceed to use it just like if:
 always two conditions per (verbose) cond! :p
 
 then again, may be someone who had previous exposure to lesser languages...


Perhaps you should ask before you critique. 
We insist on this style: 

  -- the outer cond corresponds to the structure of the data definition of the 
input 
  -- the inner one signals decision relevant for the output 
(I would use an 'if' for the inner one, but over N years of programming
as if a student might see my code one day, I have come to really, truly 
like the unconditional use of cond for the layout purpose) 



_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] Simple loop checking in beginner?

2010-11-10 Thread Sam Tobin-Hochstadt
On Wed, Nov 10, 2010 at 10:40 AM, namekuseijin namekusei...@gmail.com wrote:
 On Wed, Nov 10, 2010 at 12:13 AM, John Clements
 cleme...@brinckerhoff.org wrote:
 ;; NOW I'M A STUDENT:

 ;; only-long-strings : (listof string) - (listof string)
 ;; return a list containing the strings longer than 2 chars
 (define/noloop (only-long-strings l)
  (cond [(empty? l) empty]
        [else (cond [( 2 (string-length (first l)))
                     (cons (first l)
                           (only-long-strings (rest l)))]
                    [else (only-long-strings l)])]))

 gosh, students do suck.  I guess you teach them to use cond because
 it's a generalized if.  But then they proceed to use it just like if:
 always two conditions per (verbose) cond! :p

I disagree - the outer `cond' has 2 clauses because it it processing a
data definition - (listof string) - which has 2 clauses.  The second
`cond' clause, which processes conses, has a conditional as well, but
there's certainly nothing wrong with having the structure of your
program match the structure of your data, especially not for HtDP
programs.
-- 
sam th
sa...@ccs.neu.edu
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] Simple loop checking in beginner?

2010-11-10 Thread namekuseijin
I see the reasoning now, I apologize.  It's a good choice for
students, not so sure about ye old daily buggy sofware maintenance.

OTOH, perhaps if this practice was widespread it would lead to less
bugs or at least more maintenable software.  At least for those aware
of this idiom.

On Wed, Nov 10, 2010 at 1:44 PM, Matthias Felleisen
matth...@ccs.neu.edu wrote:

 On Nov 10, 2010, at 10:40 AM, namekuseijin wrote:

 On Wed, Nov 10, 2010 at 12:13 AM, John Clements
 cleme...@brinckerhoff.org wrote:
 ;; NOW I'M A STUDENT:

 ;; only-long-strings : (listof string) - (listof string)
 ;; return a list containing the strings longer than 2 chars
 (define/noloop (only-long-strings l)
  (cond [(empty? l) empty]
        [else (cond [( 2 (string-length (first l)))
                     (cons (first l)
                           (only-long-strings (rest l)))]
                    [else (only-long-strings l)])]))

 gosh, students do suck.  I guess you teach them to use cond because
 it's a generalized if.  But then they proceed to use it just like if:
 always two conditions per (verbose) cond! :p

 then again, may be someone who had previous exposure to lesser languages...


 Perhaps you should ask before you critique.
 We insist on this style:

  -- the outer cond corresponds to the structure of the data definition of the 
 input
  -- the inner one signals decision relevant for the output
        (I would use an 'if' for the inner one, but over N years of programming
        as if a student might see my code one day, I have come to really, truly
        like the unconditional use of cond for the layout purpose)
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] Simple loop checking in beginner?

2010-11-10 Thread Robby Findler
The value in the large comes when the data structures are more complex
(in the function below you'd use a loop or filter, of course). When
they are larger, you can pinpoint where to change your function based
on a change to your data definition.

For example, consider writing an interpreter. Now imagine the language
changes in some way -- you can read off where exactly to change the
interpreter.

Robby

On Wed, Nov 10, 2010 at 10:02 AM, namekuseijin namekusei...@gmail.com wrote:
 I see the reasoning now, I apologize.  It's a good choice for
 students, not so sure about ye old daily buggy sofware maintenance.

 OTOH, perhaps if this practice was widespread it would lead to less
 bugs or at least more maintenable software.  At least for those aware
 of this idiom.

 On Wed, Nov 10, 2010 at 1:44 PM, Matthias Felleisen
 matth...@ccs.neu.edu wrote:

 On Nov 10, 2010, at 10:40 AM, namekuseijin wrote:

 On Wed, Nov 10, 2010 at 12:13 AM, John Clements
 cleme...@brinckerhoff.org wrote:
 ;; NOW I'M A STUDENT:

 ;; only-long-strings : (listof string) - (listof string)
 ;; return a list containing the strings longer than 2 chars
 (define/noloop (only-long-strings l)
  (cond [(empty? l) empty]
        [else (cond [( 2 (string-length (first l)))
                     (cons (first l)
                           (only-long-strings (rest l)))]
                    [else (only-long-strings l)])]))

 gosh, students do suck.  I guess you teach them to use cond because
 it's a generalized if.  But then they proceed to use it just like if:
 always two conditions per (verbose) cond! :p

 then again, may be someone who had previous exposure to lesser languages...


 Perhaps you should ask before you critique.
 We insist on this style:

  -- the outer cond corresponds to the structure of the data definition of 
 the input
  -- the inner one signals decision relevant for the output
        (I would use an 'if' for the inner one, but over N years of 
 programming
        as if a student might see my code one day, I have come to really, 
 truly
        like the unconditional use of cond for the layout purpose)
 _
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

Re: [racket-dev] Simple loop checking in beginner?

2010-11-10 Thread Matthias Felleisen

A factor of 2.+. 

(We could provide a type system, take away recursion, and replace it with a 
structural induction form. It would be impossible to write infinite loops.) 


On Nov 10, 2010, at 12:41 PM, John Clements wrote:

 
 On Nov 10, 2010, at 6:50 AM, Matthias Felleisen wrote:
 
 
 Your reasoning is correct. What's the performance hit? 
 
 In order to try it, I used the legendary 12.4.2, and... uh, it seg faulted. 
 
 Okay, I submitted a bug report on that. Moving right along:
 
 Testing in the simplest way, here's what I got for permute of size 9:
 
 
 Debugging enabled, no loop protection:
 cpu time: 2520 real time: 2539 gc time: 1554
 cpu time: 1504 real time: 1523 gc time: 542
 cpu time: 1515 real time: 1534 gc time: 552
 
 Debugging enabled, with loop protection:
 cpu time: 4496 real time: 4532 gc time: 1940
 cpu time: 3653 real time: 3694 gc time: 1079
 cpu time: 3692 real time: 3730 gc time: 1112
 
 Debugging disabled, no loop protection:
 cpu time: 2181 real time: 2200 gc time: 1651
 cpu time: 1132 real time: 1152 gc time: 597
 cpu time: 1143 real time: 1163 gc time: 603
 
 Debugging disabled, with loop protection:
 cpu time: 3458 real time: 3494 gc time: 2007
 cpu time: 2434 real time: 2471 gc time: 972
 cpu time: 2424 real time: 2461 gc time: 1001
 
 ... so it's quite a bit slower. Note that a whole bunch of this slowdown in 
 the debugging enabled category is presumably due to the errortrace 
 annotation of the macro expansion.  I'm guessing that folding this into the 
 errortrace expansion would reduce its overhead quite a bit.
 
 John
 

_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


Re: [racket-dev] Simple loop checking in beginner?

2010-11-10 Thread Nadeem Abdul Hamid
HtDP in Coq? Hadn't thought of of that before...

On Wed, Nov 10, 2010 at 1:26 PM, Matthias Felleisen
matth...@ccs.neu.edu wrote:

 A factor of 2.+.

 (We could provide a type system, take away recursion, and replace it with a 
 structural induction form. It would be impossible to write infinite loops.)


 On Nov 10, 2010, at 12:41 PM, John Clements wrote:


 On Nov 10, 2010, at 6:50 AM, Matthias Felleisen wrote:


 Your reasoning is correct. What's the performance hit?

 In order to try it, I used the legendary 12.4.2, and... uh, it seg faulted.

 Okay, I submitted a bug report on that. Moving right along:

 Testing in the simplest way, here's what I got for permute of size 9:


 Debugging enabled, no loop protection:
 cpu time: 2520 real time: 2539 gc time: 1554
 cpu time: 1504 real time: 1523 gc time: 542
 cpu time: 1515 real time: 1534 gc time: 552

 Debugging enabled, with loop protection:
 cpu time: 4496 real time: 4532 gc time: 1940
 cpu time: 3653 real time: 3694 gc time: 1079
 cpu time: 3692 real time: 3730 gc time: 1112

 Debugging disabled, no loop protection:
 cpu time: 2181 real time: 2200 gc time: 1651
 cpu time: 1132 real time: 1152 gc time: 597
 cpu time: 1143 real time: 1163 gc time: 603

 Debugging disabled, with loop protection:
 cpu time: 3458 real time: 3494 gc time: 2007
 cpu time: 2434 real time: 2471 gc time: 972
 cpu time: 2424 real time: 2461 gc time: 1001

 ... so it's quite a bit slower. Note that a whole bunch of this slowdown in 
 the debugging enabled category is presumably due to the errortrace 
 annotation of the macro expansion.  I'm guessing that folding this into the 
 errortrace expansion would reduce its overhead quite a bit.

 John


 _
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev


[racket-dev] Simple loop checking in beginner?

2010-11-09 Thread John Clements
Here's a simple macro that prevents same-argument recursive calls (including 
non-tail ones).  It's illustrated by a student function that made a teeny 
mistake which would result in looping forever, but (using this macro) instead 
signals an error.  To the best of my limited knowledge, beginner is purely 
functional aside from the use of the test functions, right? So any recursive 
call with eq? args is guaranteed to loop forever, right?

Hmm... well, I suppose there's (random)... 

It seems to me that a macro like this one (or even complete memoization) could 
potentially reduce student frustration, and would not prevent students from 
writing the programs that they wanted to.

No?

John Clements



#lang racket

(require rackunit)

(define-syntax (define/noloop stx)
  (syntax-case stx ()
[(_ (funname arg ...) body ...)
 #`(define funname
 (let ()
   (define fresh-key (gensym 'funname))
   (define (funname arg ...)
 (let* ([most-recent-args (continuation-mark-set-first #f 
fresh-key)]
[these-args (list arg ...)])
   (when (and most-recent-args
  (= (length these-args)
 (length most-recent-args))
  (andmap eq? these-args most-recent-args))
 (error 'funname recursive call with identical arguments ~s is 
guaranteed to run forever. these-args))
   (with-continuation-mark fresh-key these-args
 body
 ...)))
   funname))]))

;; NOW I'M A STUDENT:

;; only-long-strings : (listof string) - (listof string)
;; return a list containing the strings longer than 2 chars
(define/noloop (only-long-strings l)
  (cond [(empty? l) empty]
[else (cond [( 2 (string-length (first l))) 
 (cons (first l) 
   (only-long-strings (rest l)))]
[else (only-long-strings l)])]))


(check-equal? (only-long-strings (cons abc (cons de (cons fgh empty
  (cons abc (cons fgh empty)))

smime.p7s
Description: S/MIME cryptographic signature
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev