![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
In article <4a8ab114@news.povray.org>,
Invisible wrote:
> ...wuh??
What? You don't program in Scheme? Why in the world would you not? :P
This program above is a prototype of the UNIX cat program. I was
wondering how people would sort of write those lines in usual
Scheme. But I guess I might be in the wrong off topic group. :-)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Daniel Bastos wrote:
> What? You don't program in Scheme? Why in the world would you not? :P
Because it looks like THAT? :-P
> This program above is a prototype of the UNIX cat program. I was
> wondering how people would sort of write those lines in usual
> Scheme. But I guess I might be in the wrong off topic group. :-)
Oh, right.
In Haskell, we just say
main = interact id
;-)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
In article <4a8abba2@news.povray.org>,
Invisible wrote:
> Daniel Bastos wrote:
>
>> What? You don't program in Scheme? Why in the world would you not? :P
>
> Because it looks like THAT? :-P
Looks interesting! :P
> In Haskell, we just say
>
> main = interact id
>
> ;-)
That's right! I should copy that! ;)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Daniel Bastos <dbastos+0### [at] toledo com> wrote:
> How strong are my imperative ways?
> #!/usr/bin/env mzscheme
> (module cat scheme/base
> (define (cat)
> (let ([ln (read-line)])
> (if (not (eq? ln eof))
> (and (display ln) (newline) (cat))
> (exit) )))
> ; main
> (cat)
> )
> %fortune | ./cat
> Let me put it this way: today is going to be a learning experience.
> %
> How would you scheme up your cat?
'cat' is a program for concatenating files. It's used like:
cat file1 file2 file3 > concatenated_files
Your program does not fulfill this role.
(Some people abuse 'cat' to concatenate one single file with nothing,
but that doesn't mean that the role of 'cat' is anything else than
concatenating files.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
In article <4a8acf7f$1@news.povray.org>,
Daniel Bastos wrote:
>> In Haskell, we just say
>>
>> main = interact id
>>
>> ;-)
>
> That's right! I should copy that! ;)
#!/usr/bin/env mzscheme
(module cat scheme/base
(define (interact f)
(let ([ln (read-line)])
(if (not (eq? ln eof))
(and (display (f ln)) (newline) (interact f))
(exit))))
(define (id x) x)
(define (cat)
(interact id))
;main
(cat)
)
%printf 'my\nbeloved\ncat\n' | ./cat
my
beloved
cat
%
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
In article <4a8ae42c@news.povray.org>,
Warp wrote:
> Daniel Bastos <dbastos+0### [at] toledo com> wrote:
>> How strong are my imperative ways?
>
>> #!/usr/bin/env mzscheme
>> (module cat scheme/base
>
>> (define (cat)
>> (let ([ln (read-line)])
>> (if (not (eq? ln eof))
>> (and (display ln) (newline) (cat))
>> (exit) )))
>
>> ; main
>> (cat)
>> )
[...]
> 'cat' is a program for concatenating files. It's used like:
>
> cat file1 file2 file3 > concatenated_files
>
> Your program does not fulfill this role.
I wasn't aware of the definition of cat. But I think it's true that
without reading files, it is unable to concatenate. After a day of
work, I can now tell one how to scheme a cat.
#!/usr/bin/env mzscheme
(module cat scheme/base
(define (interact f)
(let ([ln (read-line)])
(cond
[(not (eq? ln eof))
(and
(printf "~a\n" (f ln))
(interact f))])))
(define (id x) x)
(define (cat files)
(for-each
(lambda (x)
(with-input-from-file x
(lambda ()
(interact id))))
files))
;main
(cat (vector->list (current-command-line-arguments)))
)
With with-input-from-file, we get the stdin connected to the file
opened, so no changes in interact were required.
This cat does not handle exceptions. I might see how that works next.
Although Haskell has always looked wonderful to me, I had the
intuition that a Lisp like language would suit me better because I'm
kind of syntax minimalist. I gave up on the idea that this is good,
and went to check Haskell out. I liked it a lot, but I'm coming back
to believe that my initial intuition deserves attention.
Like someone once put it; a good language has to be hackable. I think
Lisp likes might be hackestables.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Daniel Bastos <dbastos+0### [at] toledo com> wrote:
> #!/usr/bin/env mzscheme
> (module cat scheme/base
>
> (define (interact f)
> (let ([ln (read-line)])
> (cond
> [(not (eq? ln eof))
> (and
> (printf "~a\n" (f ln))
> (interact f))])))
>
> (define (id x) x)
>
> (define (cat files)
> (for-each
> (lambda (x)
> (with-input-from-file x
> (lambda ()
> (interact id))))
> files))
>
> ;main
> (cat (vector->list (current-command-line-arguments)))
> )
>
> With with-input-from-file, we get the stdin connected to the file
> opened, so no changes in interact were required.
That's the PLT way. here's another:
#!r6rs
(import (rnrs base)(rnrs io simple)(rnrs programs))
; simple and straightforward standard R6RS scheme solution
(define (cat files)
(for-each
(lambda (file)
(call-with-input-file file
(lambda (port)
; no simple line-oriented IO in standard R6RS
; so you either write one or loop char-by-char
(let go ((c (read-char port)))
(if (not (eof-object? c))
(begin
(write-char c)
(go (read-char port))))))))
files))
(cat (cdr (command-line)))
you can run it like:
plt-r6rs cat.scm foo.txt bar.txt
> This cat does not handle exceptions. I might see how that works next.
Neither does mine. There is a file-exists? function though:
http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-10.html#node_chap_9
> Lisp likes might be hackestables.
I just love Lisp, Scheme in particular. Minimalist like C, only much higher
level. Incidentally, the only two languages I truly enjoy, for different
purposes sure.
yes, I'm aware the C solution for this particular example would be way
shorter... :P
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> 'cat' is a program for concatenating files. It's used like:
>
> cat file1 file2 file3 > concatenated_files
>
> Your program does not fulfill this role.
>
> (Some people abuse 'cat' to concatenate one single file with nothing,
> but that doesn't mean that the role of 'cat' is anything else than
> concatenating files.)
Interesting. I thought it was for concatenating a file to stdout...
Alrighty then:
import System.Environment
main = do
args <- getArgs
mapM_ (\arg -> readFile arg >>= putStr) args
That seems to work.
I'm guessing the real cat program also has assorted command-line
switches as well though?
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible wrote:
> I'm guessing the real cat program also has assorted command-line
> switches as well though?
OK, so let's ask the manpage:
http://unixhelp.ed.ac.uk/CGI/man-cgi?cat
[BTW, Google for "man cat" turns up some, uh, /interesting/ results
before this one.]
I'll see if I can't produce a full implementation...
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>> I'm guessing the real cat program also has assorted command-line
>> switches as well though?
>
> OK, so let's ask the manpage:
>
> http://unixhelp.ed.ac.uk/CGI/man-cgi?cat
Apparently POSIX only specifies the -u option; the rest is extensions.
(Common ones though, apparently.) This is apparantly typical for all
widely-known Unix commands. I guess we can thank 40,000,000 years of
backwards compatibility for that.
> I'll see if I can't produce a full implementation...
The attached program appears to do the job. There are probably still
some bugs in it though.
[I definitely can't guarantee it works the same as GNU cat, because I
don't have anything to test against. It's probably broken in it's
handling of "\n" and/or "\r", the line numbering, the text/binary
distinction, and a few other things.]
Post a reply to this message
Attachments:
Download 'us-ascii' (5 KB)
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |