Re: [racket-dev] Using clang to Build Racket on Mac OS X

2011-09-10 Thread Will M. Farr
Thanks, Matthew!  It seems to build OK now.  

Will

On Sep 11, 2011, at 6:42 AM, Matthew Flatt wrote:

> At Wed, 27 Jul 2011 10:38:44 -0500, "Will M. Farr" wrote:
>> The only wart in the process is the following: when compiling with clang or 
>> llvm-gcc with the -O4 option, which enables link-time optimization in the 
>> LLVM 
>> backend, the GC is unable to correctly determine the stack growth direction. 
>>  
>> Unfortunately, the configure script doesn't realize that it cannot determine 
>> the direction---apparently the test gets it wrong, but appears 
>> successful---so 
>> supplying the direction manually via the configure argument doesn't work.  
>> The 
>> build fails when first trying to run raco setup when the GC notes that the 
>> stack growth is inconsistent with its assumptions.  
> 
> I've pushed a fix for this problem, along with other changes to avoid
> warnings when compiling with clang.
> 



PGP.sig
Description: This is a digitally signed message part
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

[racket-dev] Using clang to Build Racket on Mac OS X

2011-07-27 Thread Will M. Farr
Hello Racket Developers,

I thought I would write a quick note about building Racket on Mac OS X 10.6.8 
with the new clang compiler (the new front-end to the LLVM compiler backend 
that is becoming the standard compiler on Mac OS X for XCode 4 and later).  
Overall, it's been a good experience.  As promised, clang seems to compile the 
C sources in the racket distribution much more quickly than gcc, and has 
better-formatted error and warning messages.  I believe that the resulting 
native code libraries make racket run faster, but haven't run any detailed 
tests (there was quite a gap between my last gcc-based build and my first 
clang-based one, so the improvements may also be due to Racket development).  

The only wart in the process is the following: when compiling with clang or 
llvm-gcc with the -O4 option, which enables link-time optimization in the LLVM 
backend, the GC is unable to correctly determine the stack growth direction.  
Unfortunately, the configure script doesn't realize that it cannot determine 
the direction---apparently the test gets it wrong, but appears successful---so 
supplying the direction manually via the configure argument doesn't work.  The 
build fails when first trying to run raco setup when the GC notes that the 
stack growth is inconsistent with its assumptions.  

I'm writing this email partly to see if anyone else has seen the error and 
knows what to do about it, and partly because I thought you might like to know 
how racket fairs on the newer OS X compiler.  If someone wants to test 
modifications to the configure script's stack growth test, I would be happy to 
take patches and test-compile them on my system.  For now, I am having great 
luck building with clang -O3; eventually, it would be nice to have the LTO, 
since that's one of the most exciting benefits of using the LLVM toolchain.

Thanks again for the Racket system!

Will

PGP.sig
Description: This is a digitally signed message part
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

[racket-dev] flvector-copy

2010-09-16 Thread Will M. Farr
Hello all,

The attached patch against the current git master adds an flvector-copy 
procedure (along with docs and tests); it's simple, but nice to have in the 
flvector library.  Let me know if there are any issues with including this in 
racket.

Thanks,
Will



0004-Added-flvector-copy-with-tests-and-docs.patch
Description: Binary data
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

Re: [racket-dev] Contract Errors in the Test Suite

2010-09-12 Thread Will M. Farr
FYI, I've submitted a bug to the bug tracker detailing this problem.

Will

On Sep 11, 2010, at 5:04 PM, Will M. Farr wrote:

> I've finished the testing of configure options.  It seems to be the places 
> library.  Running with or without optimization options, the --enable-places 
> flag to configure generates a racket that fails the contract tests in the way 
> I described in my original email.  
> 
> Will
> 
> On Sep 11, 2010, at 4:39 PM, Will M. Farr wrote:
> 
>> On Sep 11, 2010, at 4:20 PM, Robby Findler wrote:
>> 
>>> My laptop has a version of the tree
>>> from about 10 days ago and I'm not seeing any errors there. Is there
>>> something more that would help me reproduce this behavior?
>>> 
>>> Thanks,
>>> Robby
>> 
>> Huh.  Or maybe it's option 4: system/OS dependent.  I'm running on a Mac OS 
>> 10.6.4, Core 2 Duo system, compiling with gcc 4.2.1 (Apple version), in 
>> 64-bit mode (no gracket, since it doesn't work with 64-bit yet).  Configure 
>> options:
>> 
>> CFLAGS="-O3 -march=core2" CXXFLAGS="-O3 -march=core2" --enable-mac64 
>> --disable-gracket --enable-places
>> 
>> I'm trying a build right now without the optimization options to the C 
>> compiler, and with places disabled; I'll let you know whether that fixes 
>> anything.  
>> 
>> I run the test suite using 
>> 
>> bin/racket collects/tests/run-automated-tests.rkt
>> 
>> from the top-level directory of the source repository (i.e. using the 
>> newly-build racket, not the one I have installed on my system).
>> 
>> Anything in this jumping out at you as the possible source of the problem?
>> 
>> Thanks,
>> Will
> 

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


Re: [racket-dev] Contract Errors in the Test Suite

2010-09-11 Thread Will M. Farr
I've finished the testing of configure options.  It seems to be the places 
library.  Running with or without optimization options, the --enable-places 
flag to configure generates a racket that fails the contract tests in the way I 
described in my original email.  

Will

On Sep 11, 2010, at 4:39 PM, Will M. Farr wrote:

> On Sep 11, 2010, at 4:20 PM, Robby Findler wrote:
> 
>> My laptop has a version of the tree
>> from about 10 days ago and I'm not seeing any errors there. Is there
>> something more that would help me reproduce this behavior?
>> 
>> Thanks,
>> Robby
> 
> Huh.  Or maybe it's option 4: system/OS dependent.  I'm running on a Mac OS 
> 10.6.4, Core 2 Duo system, compiling with gcc 4.2.1 (Apple version), in 
> 64-bit mode (no gracket, since it doesn't work with 64-bit yet).  Configure 
> options:
> 
> CFLAGS="-O3 -march=core2" CXXFLAGS="-O3 -march=core2" --enable-mac64 
> --disable-gracket --enable-places
> 
> I'm trying a build right now without the optimization options to the C 
> compiler, and with places disabled; I'll let you know whether that fixes 
> anything.  
> 
> I run the test suite using 
> 
> bin/racket collects/tests/run-automated-tests.rkt
> 
> from the top-level directory of the source repository (i.e. using the 
> newly-build racket, not the one I have installed on my system).
> 
> Anything in this jumping out at you as the possible source of the problem?
> 
> Thanks,
> Will

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


Re: [racket-dev] Contract Errors in the Test Suite

2010-09-11 Thread Will M. Farr
On Sep 11, 2010, at 4:20 PM, Robby Findler wrote:

> My laptop has a version of the tree
> from about 10 days ago and I'm not seeing any errors there. Is there
> something more that would help me reproduce this behavior?
> 
> Thanks,
> Robby

Huh.  Or maybe it's option 4: system/OS dependent.  I'm running on a Mac OS 
10.6.4, Core 2 Duo system, compiling with gcc 4.2.1 (Apple version), in 64-bit 
mode (no gracket, since it doesn't work with 64-bit yet).  Configure options:

CFLAGS="-O3 -march=core2" CXXFLAGS="-O3 -march=core2" --enable-mac64 
--disable-gracket --enable-places

I'm trying a build right now without the optimization options to the C 
compiler, and with places disabled; I'll let you know whether that fixes 
anything.  

I run the test suite using 

bin/racket collects/tests/run-automated-tests.rkt

from the top-level directory of the source repository (i.e. using the 
newly-build racket, not the one I have installed on my system).

Anything in this jumping out at you as the possible source of the problem?

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


[racket-dev] Contract Errors in the Test Suite

2010-09-11 Thread Will M. Farr
Hello developers,

I've been compiling Racket from git a lot lately (working on some iteration 
forms that now appear in the repository---thanks Sam!), and each time I do, I 
run the test suite.  For the past few weeks (month?) I've been getting a lot of 
errors related to the contract system.  I think these should be addressed, but 
I'm not sure if I'm the one to do it; this email is an attempt to figure out 
whether there is anything I can do.  A sample of the test output appears after 
this message.  

Apparently, the failures are related to the assignment of blame in 
define/contract contracts (i.e. contracts on an individual procedure that don't 
necessarily appear in a provide form).  A somewhat cryptic comment at the 
relevant section of the test suite states (contract-test.rktl):

  ;; For some of the following tests, it may not be clear
  ;; why the blame is what it is.  The contract(s) entered
  ;; into via with-contract are between the contracting
  ;; region and its context.  If the context allows the
  ;; value to flow into other regions without contracts
  ;; that protect it from misuses in those regions, it's
  ;; the context's fault.

This sounds to me like it's saying that passing an invalid value to a 
define/contract procedure should be blamed on its definition context not the 
source of the improper value; in other words, it's the fault of the definition 
context for letting this private value out into the big, bad world where 
improper values could be provided to it by entities that have no knowledge of 
its contract.  

When the tests error out by passing an invalid value to a define/contract 
procedure, the blame is currently being assigned to the source of the invalid 
value; based on the above, the tests want it to be assigned to the definition 
context.  The conflict is what is causing the test failure.  I can see three 
possibilities for the code change that resulted in these failures:

1) The guts of the contract library have changed, and it's now assigning blame 
incorrectly.
2) The contract library was changed deliberately to assign blame to the context 
that provides the invalid value, but the tests were not changed to keep up with 
this.
3) Something about the module system has changed, and it now considers the 
defining context to be "top level" where it used to be the name of the module.  
The contract library is correctly assigning blame, but the *name* of the blame 
target has changed, and so the tests are failing to find what they are 
expecting in the blame message.

If the situation is 2 or 3, I would be happy to change the tests to expect the 
new assignment of blame so that things no longer fail all the time.  If the 
situation is 1, I doubt I can be of much help, but would be happy to be in 
touch with whomever is responsible for that code as a tester of potential 
fixes/wall to bounce ideas off of.  Either way, I think somebody should know 
about this.

Thanks,
Will

Test output follows:
-

eAmu:racket farr$ ./test.sh 

>>> racket/quiet.rktl: running...
Section(basic)
Section(unicode)
Section(rx)
Section(reading)
Section(readtable)
Section(printing)
Section(macro)
Section(syntax)
Section(procs)
Section(stx)
Section(module)
Section(numbers)
Section(unsafe)
Section(object)
Section(struct)
Section(unit)
Section(unit/sig)
Section(threads)
Section(logger)
Section(synchronization)
Section(deep)
Section(continuation-marks)
Section(prompt)
Section(wills)
Section(namespaces)
Section(modprot)
Section(chaperones)
Section(parameters)
Section(port)
Section(file)
Section(udp)
Section(file-after-udp)
Section(path)
Section(optimization)
Section(names)
Section(for)
Section(list)
Section(math)
Section(vector)
Section(function)
Section(dict)
Section(contract)

Performed 3072 expression tests (1881 value expressions, 1191 exn expressions)
and 2382 exception field tests.

Errors were:
(Section (got expected (call)))
((contract) (#(struct:exn:fail:contract:blame "foo-dc13: top-level broke the 
contract (-> number? number?) on foo-dc13; expected , given: #t" 
# #) exn-type (begin (eval (quote (module 
foo-dc13 scheme/base (require scheme/contract) (define/contract (foo-dc13 n) 
(-> number? number?) (+ n 1)) (foo-dc13 #t (eval (quote (require (quote 
foo-dc13)))
((contract) (#(struct:exn:fail:contract:blame "foo-dc14: top-level broke the 
contract (-> number? number?) on foo-dc14; expected , given: #t" 
# #) exn-type (begin (eval (quote (module 
foo-dc14 scheme/base (require scheme/contract) (provide foo-dc14) 
(define/contract (foo-dc14 n) (-> number? number?) (+ n 1) (eval (quote 
(module bar-dc14 scheme/base (require (quote foo-dc14)) (foo-dc14 #t (eval 
(quote (require (quote bar-dc14)))
((contract) (#(struct:exn:fail:contract:blame "foo-dc15: top-level broke the 
contract (-> number? number?) on foo-dc15; expected , given: #t" 
# #) exn-type (begin (eval (quote (module 
foo-dc15 scheme/base (require scheme/contract) (provide foo-dc

Re: [racket-dev] PLaneT Library of Iterations/Comprehensions

2010-08-24 Thread Will M. Farr
Dave,

Thanks a bunch for pointing out the untyped code!  I have a few questions 
below, mostly trying to understand the behavior of the macros and reconcile it 
with their names.

I'm not sure that I understand for/foldl and friends.  I think of the functions 
foldl (and foldr) as taking *one* accumulator, and filtering it through a 
function applied to each of the members of a sequence or sequences---that is, 
there are many function arguments, but only one accumulator.  But, the foldl 
here looks like 

(define-syntax (for/foldl stx)
  (syntax-case stx ()
((for/foldl accums (for-clause ...) body ...)
 (syntax/loc stx
   (call-with-values 
   (lambda ()
 (for/fold accums (for-clause ...) body ...))
 (lambda args (car args)))

That is, it has many accumulators, but returns only the first.  (I tried 
defining the code you linked to at the REPL, and it barfed on some of the 
...'s, so I wasn't able to test this assertion.  I'm sure that I'm just missing 
some libraries.)  Am I confused?  This sounds more like for/fold/head, or 
for/fold/first, or something like that?

I'm similarly a bit unhappy with the name for for/filter.  The filter procedure 
takes a predicate, and removes any items from its list argument that don't 
satisfy the predicate.  The for/filter macro is like a (hypothetical) 
for/lists, followed by a removal of the false elements.  Is there possible a 
better name for this?  How often do you find yourself using the multi-valued 
version (i.e. could we have a single-valued for/not-false or something, that 
gets most of the use cases)?

I like for/append without reservation, and have added it to my local iteration 
branch, and I'll forward it to Sam once I've built the code and it passes some 
tests.  Thanks again for suggesting these forms, Dave.

Will

On Aug 24, 2010, at 2:55 AM, Dave Gurnell wrote:

> I use these guys all the time:
> 
>   http://github.com/untyped/unlib/blob/master/for.ss
> 
> No guarantees that I'm not duplicating other peoples' efforts.
> 
> Cheers,
> 
> -- Dave
> 
> On 22 Aug 2010, at 07:26, Noel Welsh wrote:
> 
>> Hi Will,
>> 
>> My "numerics" package on Github has for/vector with some slight
>> extensions to yours. I think it also has more error checking so you
>> might want to look at it. I also have for/fold/vector and some
>> sequence abstractions. The code is all parameterised at expansion time
>> by the vector representation.
>> 
>> http://github.com/noelwelsh/numeric
>> 
>> N.
>> 
>> 
>> On Wed, Aug 18, 2010 at 5:02 PM, Will M. Farr  wrote:
>>> Hello all,
>>> 
>>> I've been thinking for a while about putting together a PLaneT library of 
>>> some iteration/comprehension forms that I often use that are not found in 
>>> the racket core.  Right now, I have a small it-comp.plt local PLaneT 
>>> package that contains
>>> 
>>> for/vector
>>> for/flvector
>>> in-flvector
>>> 
>>> The for/... forms have the option of having a first expression that gives 
>>> the length of the resulting object (similar to srfi-42's 
>>> vector-of-length-ec form) to allow generating more efficient code:
>>> 
>>> (for/vector ((x (in-range 3))) x) => (vector 0 1 2)
>>> (for/vector 3 ((x (in-range 3))) x) => (vector 0 1 2) ; but more efficiently
>>> 
>>> I'll be adding more forms from time to time, as I need them.  Eventually, 
>>> I'll release this to PLaneT, but I thought I might ask the community two 
>>> questions first:
>>> 
>>> 1. Am I duplicating the functionality of some library?  (If so, I'll just 
>>> contribute to that instead.)
>>> 2. Do you have any iteration "favorites" that I should include in the 
>>> library?  (Code welcome, but I'm also happy to implement suggestions 
>>> myself.)
>>> 
>>> Alternately, if you guys want to add these to the core, I'd be happy to 
>>> contribute code and tests
>>> 
>>> Thanks,
>>> Will
>>> _
>>> For list-related administrative tasks:
>>> http://lists.racket-lang.org/listinfo/dev
>>> 
>> _
>> For list-related administrative tasks:
>> http://lists.racket-lang.org/listinfo/dev
> 
> _
>  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] gc vs assignment

2010-08-24 Thread Will M. Farr
On Aug 24, 2010, at 10:46 AM, Matthias Felleisen wrote:

> (I don't quite understand why there's no extra cost for the second access, 
> but I'll think about it and figure it out.)

If I understand things correctly, the short answer is "fancy hardware."  The 
page is marked as read-only in the MMU, so a write incurs a page fault.  The 
page fault is trapped by the GC, which records the page in a table of 
"written-to pages", marks it read-write in the MMU, and continues the program.  
Now, any write to that page is just like a write to anywhere in memory, but the 
GC knows to scan the page.  This type of thing is only possible with the 
support in hardware for these sort of read-only page marks.

Do I have it right?

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


Re: [racket-dev] [plt] Push #20898: master branch updated

2010-08-23 Thread Will M. Farr
On Aug 23, 2010, at 7:40 AM, Matthew Flatt wrote:
> 
> Maybe you want to thread the vector index through using `for/fold'
> instead of drawing the index from a sequence. The expansion could
> insert enough `#:when' clauses to compare the index to the length
> before each nested iteration.
> 

This is exactly what I have decided to do.  New patches attached.  Let me know 
if you want me to combine them into one.

Will



0002-Updates-to-for-vector-for-flvector-forms-and-documen.patch
Description: Binary data


0003-New-updates-to-for-vector-for-vector-for-flvector-an.patch
Description: Binary data
_
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

Re: [racket-dev] [plt] Push #20898: master branch updated

2010-08-22 Thread Will M. Farr
Noel,

Thanks for sharing your code, and for the comments.  Let me see if I understand 
this correctly: the following code should produce a total, a vector whose 
elements are the partial sums of elements at lower indices than the 
corresponding element of the input vector, and a vector whose elements are 
partial sums of elements at the index and lower indices of the input vector, 
right?

(define (total-and-partial-sums v)
  (for/fold/vector ((sum 0))
((i (vector-length v) 2) ;; Index, length, and two result vectors
 (x (in-vector v)))
(let ((sum-including-x (+ sum x)))
  (values sum-including-x sum sum-including-x ; The last two values are 
stored in the result vectors, first goes back in the fold

(total-and-partial-sums '#(1 2 3 4))
; => (values 10 (vector 0 1 3 6) (vector 1 3 6 10))

I can see how that would be very useful.  I see that you define for/vector 
using for/fold/vector, so the final body form of for/vector can produce 
multiple vectors, if the final expression in the body ... produces multiple 
values.  Also, you require naming the index, no?  So, the major differences are:

1. In my forms, the length is optional, and distinguished (when provided) from 
the for-clauses by a keyword argument.  In yours, it must be provided as the 
first for-clause (thus requiring that the index be named).

2. In my forms, the final body expression must produce exactly one value, which 
becomes the vector element.  In yours, the final body expression must produce 
exactly as many values as the third argument to the length clause (if provided) 
or 1 (if no third argument is present).  

As for difference 1, I think it's nice to be able to avoid providing a length 
if I don't want to.  Sometimes I may not really care about the efficiency of 
the loop, but will later need a vector, in which case it's a lot less effort to 
use (for/vector ((i (in-range 3))) ...) than to have to provide a length.  I 
also prefer the "distinguished" #:length keyword instead of shoehorning the 
length argument into a not-really-for-clause.  I'm curious what others think, 
however.

Difference #2 seems more significant to me.  I really like the idea of being 
able to produce multiple vectors simultaneously---as you say, it can have 
efficiency benefits and also be really convenient.  However, note that the 
for/list form does not allow multiple values from the last body expression, so 
there is an argument from consistency to prohibit it in for/vector as well.  
I'd be open to adding another keyword argument, however, to designate some 
number of vectors (independently of the presence or absence of the #:length 
keyword) for the output.  I'll put that in the next version, and we can see 
what other people think.  As with the #:length argument, I would prefer this to 
be a separate keyword---maybe #:num-vecs, maybe something else---rather than 
trying to fit it into a special for-clause.

Will


On Aug 22, 2010, at 4:11 PM, Noel Welsh wrote:

> On Sun, Aug 22, 2010 at 9:36 PM, Will M. Farr  wrote:
>> Matthew & co,
> ...
>> I'll make sure to throw a syntax error if I see a #:when in the for-clauses, 
>> and I think I should give up on the for*/vector #:length variant.  I was 
>> hoping that you would have some sort of neat trick to keep a running counter 
>> during the nested iteration
> 
> I'm pretty sure this will exclude a lot of my code. I'll have to check 
> tomorrow.
> 
> My for/vector allows one to construct multiple vectors in one
> iteration. This is fairly useful to efficient code. I also bind the
> length to a name. I thought I checked that this counter was exactly
> the length after the comprehension terminated, but it appears I don't.
> Code is below.
> 
> You won't be surprised to hear I prefer my variant ;-).  I have uses
> for every feature that I can dreg up if anyone is interested. I'm keen
> to see a for/vector comprehension in Racket.
> 
> N.
> 
>  (define-syntax (for/fold/vector stx)
>(syntax-case stx ()
>  [(for/fold/vector
>([accum-id init-expr] ...)
>([idx length] for-clause ...)
>body ...)
>   (syntax
>(for/fold/vector
> ([accum-id init-expr] ...)
> ([idx length 1] for-clause ...)
> body ...))]
> 
>  [(for/fold/vector
>([accum-id init-expr] ...)
>([idx length n-vectors])
>body ...)
>   (syntax
>(let ([l length])
>  (for/fold/vector
>   ([accum-id init-expr] ...)
>   ([idx l n-vectors] [_ (in-range l)])
>   body ...)))]
> 
>  [(for/fold/vector
>()
>([idx length n-vectors] for-clause0 for-clause ...)
>body ...)
>   (with-syntax ([(v-id ...)
>  (datum-

Re: [racket-dev] [plt] Push #20898: master branch updated

2010-08-22 Thread Will M. Farr
Matthew & co,

On Aug 21, 2010, at 7:14 AM, Matthew Flatt wrote:

> I didn't think of this before, but probably you should add a check that
> the length expression proceduces a nonnegative exact integer:
> 
> (syntax/loc stx
>   (let ((len length-expr))
> (unless (exact-nonnegative-integer? len)
>   (raise-type-error 'for/vector "exact nonnegative integer" len))
> (let ((v (make-vector len)))
>   (for ((i (in-naturals))
> for-clause ...)
> (vector-set! v i body))
>   v)))

Absolutely.  I'll take care of it.  

> More things that I didn't think of below...
> 
>> As for the issue 
>> of a #:size that doesn't match the length of the iteration, I have been 
>> thinking about adding a check inside the loop (for sizes that are too 
>> small), 
>> and a check outside the loop (for sizes that are too large).  If the size 
>> does 
>> not match the number of loop iterations would it be better to (error 
>> 'for/vector "loop iterations (~a) and vector size (~a) do not match" iter 
>> size), raise one of the exn:fail:contract type exceptions, or manually 
>> construct a blame object and (raise-blame-error ...), or ...?  If it were 
>> simply my code, I would just call (error ...), but that's maybe not the best 
>> in a general purpose library.
> 
> A `exn:fail:contract' exception would be the right one. It's probably
> easiest to use `raise-mismatch-error'.
> 
> It might also be ok to use
> 
>  (i (in-range 0 len))
> 
> and say that the loop stops when either the sequence runs out or the
> number of iterations matches the length. I'd be happy with that but i
> can imagine that others might prefer an error.

I think I prefer this second approach; maybe there is sometimes a use for 
creating a vector that is longer than its initially set length.  For example, I 
could imagine having an extendable vector implementation where you want to 
leave some space at the end for future expansion.

> Either choice --- error or stopping --- interacts awkwardly with
> `for*/vector'. If you've going to raise an exception, the natural thing
> to do with `for/vector' would be to stop as soon as the sequence goes
> too far. But `for*/vector' with a length currently just uses
> `for*/vector' without the length; you could check afterward, but that
> would be different than the natural choice for `for/vector'.
> 
> Along similar lines, every `for/vector' is a `for*/vector' in a way,
> because a `#:when' clause can introduce a nesting. The `for/vector'
> macro with an without a length behaves very differently than the one
> with a length when a `#:when' clause is used.
> 
> Maybe `for/vector' with a length clause should be syntactically
> restricted to have no `#:when' clauses, and maybe there just shouldn't
> be a variant of `for*/vector' that supports `#:length'.

I'll make sure to throw a syntax error if I see a #:when in the for-clauses, 
and I think I should give up on the for*/vector #:length variant.  I was hoping 
that you would have some sort of neat trick to keep a running counter during 
the nested iteration

I'll send Sam the latest when I'm done with the modifications.

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


Re: [racket-dev] [plt] Push #20898: master branch updated

2010-08-20 Thread Will M. Farr
Matthew,

Thanks very much for the comments.  I'll get to work preparing an updated 
version using #:size soon, and send it to Sam for pushing.  As for the issue of 
a #:size that doesn't match the length of the iteration, I have been thinking 
about adding a check inside the loop (for sizes that are too small), and a 
check outside the loop (for sizes that are too large).  If the size does not 
match the number of loop iterations would it be better to (error 'for/vector 
"loop iterations (~a) and vector size (~a) do not match" iter size), raise one 
of the exn:fail:contract type exceptions, or manually construct a blame object 
and (raise-blame-error ...), or ...?  If it were simply my code, I would just 
call (error ...), but that's maybe not the best in a general purpose library.

Will

On Aug 19, 2010, at 5:57 PM, Matthew Flatt wrote:

> At Thu, 19 Aug 2010 18:45:43 -0400, sa...@racket-lang.org wrote:
>> +(define-syntax for*/flvector
>> +  (lambda (stx)
>> +(syntax-case stx ()
>> +  ((for*/flvector (for-clause ...) body)
>> +   (syntax/loc stx
>> + (list->flvector (for*/list (for-clause ...) body
>> +  ((for*/flvector length-expr (for-clause ...) body)
>> +   (syntax/loc stx
>> + (for*/flvector (for-clause ...) body))
> 
> 
> I'm not comfortable with overloading based on the number of forms (the
> same with `for/vector' and `for*/vector'), since the `for' forms
> normally allow multiple expressions and internal definitions in the
> `for' body.
> 
> It would be better to use a `#:size' keyword when supplying a specific
> size instead of relying on the number of forms within `for/vector'.
> 
>> +...@defform*[((for/vector (for-clause ...) body)
>> +   (for/vector length-expr (for-clause ...) body))]
> 
> Along the same lines: the `body' meta-variable must always be followed
> by `...+' in a syntax description. If you allow only one expression,
> it's `expr' insteda of `body'. (But I think the solution here is to
> change the syntax so that the docs will have `body ...+'.)
> 
>> +...@defform*[((for*/vector (for-clause ...) body)
>> +   (for*/vector length-expr (for-clause ...) body))])]{
>> +
>> +Iterates like @scheme[for] or @scheme[for*], but the values of the
>> +...@scheme[body] expression are placed in a vector whose length is the
>> +number of iterations.  The optional @scheme[length-expr], if present,
>> +is evaluated to determine the length of the vector in advance of the
>> +iteration; if @scheme[length-expr] is provided, the computation is
>> +more efficient.}
> 
> The documentation doesn't answer the question that you asked before,
> which is what happens when the result of `length-expr' doesn't match
> the number of iterations. There appear to be no tests for that case,
> either.
> 
> _
>  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] PLaneT Library of Iterations/Comprehensions

2010-08-19 Thread Will M. Farr
Sam,

On Aug 18, 2010, at 1:39 PM, Sam Tobin-Hochstadt wrote:

>> 
>> The for/... forms have the option of having a first expression that gives 
>> the length of the resulting object (similar to srfi-42's vector-of-length-ec 
>> form) to allow generating more efficient code:
>> 
>> (for/vector ((x (in-range 3))) x) => (vector 0 1 2)
>> (for/vector 3 ((x (in-range 3))) x) => (vector 0 1 2) ; but more efficiently
> 
> What does this do if the specified length is wrong?

If the length is too short, then there will be a vector access error with the 
correct syntax location (though it may be a bit cryptic); if the length is too 
long, then the returned vector will have some slots at the end that are 
undefined (i.e. filled with whatever (make-vector NN) produces).  I think this 
kinda sucks, but I don't see any way to grab the length of a (for ...) form 
before it's run to check for consistency (in fact, I'm pretty sure you can't, 
since for loops can have #:while clauses that turn computation of the length 
into the halting problem).  In my opinion, offering the fast path (the slow 
path makes a list first, then calls (list->vector ...) on the result, so the 
fast path should be a big win both in memory and speed) is worth the risk, but 
I'd be interested to hear what you think.

I'm currently preparing the patch you requested; I'll let you know when it 
compiles and passes the tests on my system (which takes a while, since I have 
to build the whole racket environment).

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


[racket-dev] PLaneT Library of Iterations/Comprehensions

2010-08-18 Thread Will M. Farr
Hello all,

I've been thinking for a while about putting together a PLaneT library of some 
iteration/comprehension forms that I often use that are not found in the racket 
core.  Right now, I have a small it-comp.plt local PLaneT package that contains

for/vector
for/flvector
in-flvector

The for/... forms have the option of having a first expression that gives the 
length of the resulting object (similar to srfi-42's vector-of-length-ec form) 
to allow generating more efficient code:

(for/vector ((x (in-range 3))) x) => (vector 0 1 2)
(for/vector 3 ((x (in-range 3))) x) => (vector 0 1 2) ; but more efficiently

I'll be adding more forms from time to time, as I need them.  Eventually, I'll 
release this to PLaneT, but I thought I might ask the community two questions 
first:

1. Am I duplicating the functionality of some library?  (If so, I'll just 
contribute to that instead.)
2. Do you have any iteration "favorites" that I should include in the library?  
(Code welcome, but I'm also happy to implement suggestions myself.)

Alternately, if you guys want to add these to the core, I'd be happy to 
contribute code and tests

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