POV-Ray : Newsgroups : povray.off-topic : how to scheme a cat up? Server Time
5 Sep 2024 13:11:31 EDT (-0400)
  how to scheme a cat up? (Message 11 to 20 of 22)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 2 Messages >>>
From: Invisible
Subject: Re: how to scheme a cat up?
Date: 19 Aug 2009 06:20:32
Message: <4a8bd1f0$1@news.povray.org>
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

From: Invisible
Subject: Re: how to scheme a cat up?
Date: 19 Aug 2009 08:52:55
Message: <4a8bf5a7$1@news.povray.org>
>> 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)

From: Mike Raiford
Subject: Re: how to scheme a cat up?
Date: 19 Aug 2009 09:10:01
Message: <4a8bf9a9$1@news.povray.org>
Invisible wrote:

> 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.

And back then, primitive humans really enjoyed watching the monkeys work 
the abacuses while a cat command was being executed. Or was that 
primitive humans really enjoyed watching the monkeys execute a cat?

I can't remember. That was a long time ago ;)

-- 
~Mike


Post a reply to this message

From: Daniel Bastos
Subject: Re: how to scheme a cat up?
Date: 19 Aug 2009 10:33:58
Message: <4a8c0d56$1@news.povray.org>
In article <4a8b7a38@news.povray.org>,
Daniel Bastos wrote:

> This cat does not handle exceptions. I might see how that works next.

Looks like this suffices.

(define (sigint v)
  (fprintf (current-error-port) "^C\n"))

;main
(with-handlers ([exn:break? (lambda (v) (sigint v))])
  (cat (vector->list (current-command-line-arguments))))

It's interesting that I need to (exit) from sigint. What if I would
like to ignore that signal, or continue somehow? No idea what to do.

Hey, if you're very curious, there's some information in v. :-)


Post a reply to this message

From: Daniel Bastos
Subject: Re: how to scheme a cat up?
Date: 19 Aug 2009 11:00:49
Message: <4a8c13a1$1@news.povray.org>
In article <web.4a8b9c8c606eeda4cb3dd3d0@news.povray.org>,
nemesis wrote:

> Daniel Bastos <dbastos+0### [at] toledocom> 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:

By the way, I'm studying Scheme through PLT due to a clue from
authority, which I gathered. I absolutely know nothing about
implementations, but I saw this guy who seems to do his homework using
PLT, so instead of MIT, I picked PLT. Clearly at this point it doesn't
matter, but I already think about portability. Can you give me a word
on portability? On UNIX, I use POSIX as a reference, even though I
don't consider it a standard in a profound way; it works as a document
to help me understand what is like to be common out there. I'd like
that in Scheme.

>
> #!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)))

I've kinda been able to read this; which is cool. But I don't really
get the purpose of ``go'' here.

>> 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.

Same here.

> yes, I'm aware the C solution for this particular example would be way
> shorter... :P

I see it as the same thing; there isn't anything very high level about
cat that could really be taken advantage of a very high level language.

Here's the essence of cat from AT&T UNIX version 7.

while (--argc > 0) {
  if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0')
  	fi = stdin;
  else {
  	if ((fi = fopen(*argv, "r")) == NULL) {
  		fprintf(stderr, "cat: can't open %s\n", *argv);
  		continue;
  	}
  }
  fstat(fileno(fi), &statb);
  if (statb.st_dev==dev && statb.st_ino==ino) {
  	fprintf(stderr, "cat: input %s is output\n",
  	   fflg?"-": *argv);
  	fclose(fi);
  	continue;
  }
  while ((c = getc(fi)) != EOF)
  	putchar(c);
  if (fi!=stdin)
		fclose(fi);
}

Hey, looking at this very old cat, I can see that Warp is going to say
that our cats aren't cats after all; we don't read the stdin. And
he'll be right.


Post a reply to this message

From: Daniel Bastos
Subject: Re: how to scheme a cat up?
Date: 19 Aug 2009 11:07:16
Message: <4a8c1524$1@news.povray.org>
In article <4a8bba80$1@news.povray.org>,
Invisible wrote:

> 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...

It is. :-) In the same order in which they are read.

> 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?

Your cat has a disease, common in recently seen cats, the makes it
ignore the stdin.


Post a reply to this message

From: Daniel Bastos
Subject: Re: how to scheme a cat up?
Date: 19 Aug 2009 11:10:43
Message: <4a8c15f3@news.povray.org>
In article <4a8bf5a7$1@news.povray.org>,
Invisible wrote:

> 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 can't even say -u is really necessary.

> The attached program appears to do the job. There are probably still 
> some bugs in it though.

That program is no cat. That's Garfield.


Post a reply to this message

From: nemesis
Subject: Re: how to scheme a cat up?
Date: 19 Aug 2009 15:24:29
Message: <4a8c516d$1@news.povray.org>
Daniel Bastos escreveu:
> In article <web.4a8b9c8c606eeda4cb3dd3d0@news.povray.org>,
> nemesis wrote:
> By the way, I'm studying Scheme through PLT due to a clue from
> authority, which I gathered.

PLT is amazing, an excellent choice.  I hope you also knows how to use 
the combination keys for easily navigating/editing Lisp code: 
alt+up/down to go up/down a parenthetical level, alt+left/right to go to 
the next beginning or end, combine with shift to select and copy/paste 
at will.  Turns editing Lisp code a breeze and almost as good as with emacs.

> I absolutely know nothing about
> implementations,

Far too many to know.  It's a minimalist language and several people for 
several years tried their hands into making something unique, with 
unique frameworks for it.  Some of the bigger and best: PLT, Gambit, 
Bigloo, Chez, SISC etc.  In recent years, many excellent performant and 
compliant with the latest language standard, R6RS, showed up:  ikarus 
and ypsilon come to mind.

> matter, but I already think about portability. Can you give me a word
> on portability?

Sure:  many Scheme implementations are pretty portable. :)

Use what the implementation provides for system level access and you 
should be fine.

> On UNIX, I use POSIX as a reference, even though I

Forget about low-level system access.  Leave that to C.

> don't consider it a standard in a profound way; it works as a document
> to help me understand what is like to be common out there. I'd like
> that in Scheme.
> 
>> #!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)))
> 
> I've kinda been able to read this; which is cool. But I don't really
> get the purpose of ``go'' here.

let creates lexical scopes.  It's actually just a macro.

(let ((x 2)) (+ 1 x))

turns into:

((lambda (x) (+ 1 x)) 2)

(let label (bindings ...) ...) is called a named let.  It turns the let 
body into a full fleged local function of name label.

It's most immediate use is to create loops out of functions calls, since 
as you know, there's no such builtin looping facility in functional 
languages.

I could have defined an inner or outer function named go or whatever, 
but simply used let.  The normal let bindings turn into parameters with 
initial values for the function.  Thus,

(go (read-char port))

calls the function again.  Beware that many people enjoy creating such 
loops like (let loop (...) ...) but the label may be any of your choice. 
  Also, the body may sport several exits as stop condition.

There's no stack growing because of that last call, since the last call 
is the call to the function itself.  It's in tail position and suffers 
an optimization called tail call elimination, which instead of actually 
creating a new call stack, it replaces the current arguments with the 
new arguments and goes to the first instruction again.  It can do it 
because it's in tail position, it's the last thing done in a function 
body and it can be proved that no value other than the final value is 
needed for the return of the function as whole.  So, no need for a stack.

If the last call was something like (+ 1 (go ...)) than the call to go 
would not be in tail position because some expression is expecting the 
value it returns.

>> yes, I'm aware the C solution for this particular example would be way
>> shorter... :P
> 
> I see it as the same thing; there isn't anything very high level about
> cat that could really be taken advantage of a very high level language.
> 
> Here's the essence of cat from AT&T UNIX version 7.
> 
> while (--argc > 0) {
>   	fi = stdin;
>   while ((c = getc(fi)) != EOF)
>   	putchar(c);
>   if (fi!=stdin)
> 		fclose(fi);
> }

that is the short essence without error handling. :)

> Hey, looking at this very old cat, I can see that Warp is going to say
> that our cats aren't cats after all; we don't read the stdin. And
> he'll be right.

Bah, just a matter of reorganizing a bit adding a short if before for-each:

(define (cat files)
   (define (process 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))))))
   (if (null? files) (process (current-input-port))
       (for-each
        (lambda (file) (call-with-input-file file process))
        files)))

perhaps you should add (rnrs io ports) to the import list.

If you want to know more about Scheme:
http://www.r6rs.org/
http://schemers.org/


-- 
a game sig: http://tinyurl.com/d3rxz9


Post a reply to this message

From: Warp
Subject: Re: how to scheme a cat up?
Date: 19 Aug 2009 17:36:19
Message: <4a8c7052@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> The attached program appears to do the job.

  I think you have way too much time on your hands... :P

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: how to scheme a cat up?
Date: 20 Aug 2009 04:05:58
Message: <4a8d03e6$1@news.povray.org>
Warp wrote:
> Invisible <voi### [at] devnull> wrote:
>> The attached program appears to do the job.
> 
>   I think you have way too much time on your hands... :P

You *think*?!

I thought we already settled this one, many years ago. ;-)

Besides, it's not a very long program, and I haven't actually tested it 
properly. (As you probably know, testing typically takes a really long 
time.)


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 2 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.