Commit Message
Here's where I'm currently at with 'wc'. Currently I'm getting an error
about having the wrong number of arguments for lambda (I assume)
;;; /home/efraim/workspace/guix/guix/build/bournish.scm:143:2: warning:
wrong number of arguments to `#<tree-il (lambda () (lambda-case (((lines
words chars) #f #f #f () (lines-24244 words-24245 chars-24246)) (apply
(toplevel format) (const #t) (const "~a ~a ~a ~a~%") (lexical lines
lines-24244) (lexical words words-24245) (lexical chars chars-24246)
(lexical file file-24242)))))>'
It's not ready as-is, but I wanted to show what I had so far :)
Comments
On 2016-05-26 14:27, Efraim Flashner wrote:
> Here's where I'm currently at with 'wc'. Currently I'm getting an error
> about having the wrong number of arguments for lambda (I assume)
[...]
> +(define (wc-command file)
> + ((lambda (lines words chars) ; lambda doesn't like 3 variables
> + (format #t "~a ~a ~a ~a~%" lines words chars file))
> + (call-with-input-file file lines+chars)))
[...]
>
> ;;; /home/efraim/workspace/guix/guix/build/bournish.scm:143:2: warning:
> wrong number of arguments to `#<tree-il (lambda () (lambda-case
> (((lines
> words chars) #f #f #f () (lines-24244 words-24245 chars-24246)) (apply
> (toplevel format) (const #t) (const "~a ~a ~a ~a~%") (lexical lines
> lines-24244) (lexical words words-24245) (lexical chars chars-24246)
> (lexical file file-24242)))))>'
I think you might just be missing a 'call-with-values':
(define (wc-command file)
(call-with-values
(call-with-input-file file lines+chars)
(lambda (lines words chars) ...)))
Eric Bavier <ericbavier@openmailbox.org> writes:
> On 2016-05-26 14:27, Efraim Flashner wrote:
>> Here's where I'm currently at with 'wc'. Currently I'm getting an error
>> about having the wrong number of arguments for lambda (I assume)
> [...]
>> +(define (wc-command file)
>> + ((lambda (lines words chars) ; lambda doesn't like 3 variables
>> + (format #t "~a ~a ~a ~a~%" lines words chars file))
>> + (call-with-input-file file lines+chars)))
> [...]
>>
>> ;;; /home/efraim/workspace/guix/guix/build/bournish.scm:143:2: warning:
>> wrong number of arguments to `#<tree-il (lambda () (lambda-case
>> (((lines
>> words chars) #f #f #f () (lines-24244 words-24245 chars-24246)) (apply
>> (toplevel format) (const #t) (const "~a ~a ~a ~a~%") (lexical lines
>> lines-24244) (lexical words words-24245) (lexical chars chars-24246)
>> (lexical file file-24242)))))>'
>
> I think you might just be missing a 'call-with-values':
>
> (define (wc-command file)
> (call-with-values
> (call-with-input-file file lines+chars)
> (lambda (lines words chars) ...)))
I believe this should be
(define (wc-command file)
(call-with-values
(lambda ()
(call-with-input-file file lines+chars))
(lambda (lines words chars)
...)))
since both arguments to call-with-values must be procedures.
By the way, I prefer SRFI-11 let-values (standardized in R7RS):
(define (wc-command file)
(let-values (((lines words chars)
(call-with-input-file file lines+chars)))
...))
The large number of parentheses involved are annoying at first, but as I
used it more often I grew accustomed to it and aren't bothered at all
anymore, neither in writing nor reading the code. I also had some valid
uses of let*-values occasionally; I find it neat how it allows "piping"
a number of different values through a sequence of procedures, without
having to allocate any intermediate data structures.
Taylan
On Fri, May 27, 2016 at 11:28 AM, Taylan Ulrich Bayırlı/Kammer
<taylanbayirli@gmail.com> wrote:
> By the way, I prefer SRFI-11 let-values (standardized in R7RS):
>
> (define (wc-command file)
> (let-values (((lines words chars)
> (call-with-input-file file lines+chars)))
> ...))
>
> The large number of parentheses involved are annoying at first, but as I
> used it more often I grew accustomed to it and aren't bothered at all
> anymore, neither in writing nor reading the code. I also had some valid
> uses of let*-values occasionally; I find it neat how it allows "piping"
> a number of different values through a sequence of procedures, without
> having to allocate any intermediate data structures.
I second this. I got very good mileage out of let*-values while
making my game for the last Lisp Game Jam.
https://git.dthompson.us/lisp-game-jam-2016-spring.git/blob/HEAD:/lisparuga/world.scm#l273
- Dave
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -21,11 +22,13 @@
#:use-module (system base compile)
#:use-module (system repl command)
#:use-module (system repl common)
+ ;#:use-module (ice-9 streams)
#:use-module (ice-9 rdelim)
#:use-module (ice-9 match)
#:use-module (ice-9 ftw)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
+ #:use-module (srfi srfi-41)
#:export (%bournish-language))
;;; Commentary:
@@ -103,6 +106,56 @@ characters."
((@ (guix build utils) dump-port) port (current-output-port))
*unspecified*)))
+(define (file-size file)
+ (stat:size (stat file)))
+
+(define (wc-c-command file)
+ ;; Faster when only `wc -c' is called
+ (file-size file))
+
+(define (wc-l-command file)
+ ;; Faster when only `wc -l' is called
+ (stream-length
+ (stream-filter
+ (lambda (chr)
+ (char=? chr #\newline))
+ (port->stream (open-file file "r")))))
+
+;(define (wc-l-command file)
+; (call-with-input-file file
+; (lambda (port)
+
+(define (lines+chars port)
+ ;; Return the number of lines and number of chars read from PORT.
+ (let loop ((lines 0) (words 0) (chars 0))
+ (match (read-char port)
+ ((? eof-object?) ;done!
+ (values lines words chars))
+ (#\newline ;recurse
+ (loop (1+ lines) (1+ words) (1+ chars)))
+ ((and (char-set<= ? char-set:blank) ; need to fix/replace the '?'
+ (char-set<= (peek-char port) char-set:graphic))
+ (loop lines (1+ words) (1+ chars)))
+ (_ ;recurse
+ (loop lines words (1+ chars))))))
+
+(define (wc-command file)
+ ((lambda (lines words chars) ; lambda doesn't like 3 variables
+ (format #t "~a ~a ~a ~a~%" lines words chars file))
+ (call-with-input-file file lines+chars)))
+
+; let-values is undefined
+; (let-values (((lines words chars)
+; (call-with-input-file file lines+chars)))
+; (format #t "~a ~a ~a ~a~%" lines chars words file)))
+
+;(define (wc-command file)
+; (let ((wc-l (wc-l-command file))
+; (wc-w (wc-w-command file))
+; (wc-c (wc-c-command file)))
+; (format #t "~{~a ~}\n"
+; (list wc-l wc-w wc-c file))))
+
(define (help-command . _)
(display "\
Hello, this is Bournish, a minimal Bourne-like shell in Guile!
@@ -129,7 +182,8 @@ commands such as 'ls' and 'cd'; it lacks globbing, pipes---everything.\n"))
("help" ,help-command)
("ls" ,ls-command)
("which" ,which-command)
- ("cat" ,cat-command)))
+ ("cat" ,cat-command)
+ ("wc" ,wc-command)))
(define (read-bournish port env)
"Read a Bournish expression from PORT, and return the corresponding Scheme