sxml or guile bug?

2023-04-30 Thread Christopher Lam
Hi, we've identified an unusual behaviour in writing a test in gnucash. Can
anyone reproduce and confirmit?

I paste a simple .scm file, and its input test-file.html. Now, in
sxml-bug.scm, modify the  index - from -1 to -2 i.e. access the
last/penultimate row etc.

Odd negative indices work, even negative indices lead to error. Odd (haha)
bug. See report for (tr -2) for example, pasted below.

 sxml-bug.scm =
(use-modules (sxml simple))
(use-modules (sxml xpath))
(use-modules (ice-9 textual-ports))
(define html (call-with-input-file "/tmp/test-file.html" get-string-all))
(define sx (xml->sxml html))

;; note this path: try different indices for the tr tag:
;; odd numbers -1 -3 -5 are ok
;; even numbers -2 -4 -6 will fail
(define path '(// (table 1) // (tr -1)))

(format #t "html=[~s]\n" html)
(format #t "sxpath is [~s]\n" path)
(format #t "result is [~s]\n" ((sxpath path) sx))


And the backtrace with -2

=
Backtrace:
In ice-9/boot-9.scm:
  1752:10 18 (with-exception-handler _ _ #:unwind? _ # _)
In unknown file:
  17 (apply-smob/0 #)
In ice-9/boot-9.scm:
724:2 16 (call-with-prompt _ _ #)
In ice-9/eval.scm:
619:8 15 (_ #(#(#)))
In ice-9/boot-9.scm:
   2836:4 14 (save-module-excursion _)
  4388:12 13 (_)
In /home/user/sources/sxml-bug.scm:
20:30 12 (_)
In sxml/xpath.scm:
   254:18 11 (map-union # …)
   254:18 10 (map-union # …)
   254:18  9 (map-union # …)
   254:18  8 (map-union # …)
   254:18  7 (map-union # …)
   252:22  6 (map-union # …)
   252:22  5 (map-union # …)
   254:18  4 (map-union # …)
   254:18  3 (map-union # …)
   252:22  2 (map-union # …)
   484:19  1 (loop _ ((tr -6)))
   181:24  0 (_ _)

sxml/xpath.scm:181:24: yikes!
=
  read rows from the bottom

  From 01/01/23 to 12/31/23

   Sorting / Add indenting columns : Disabled
   Sorting / Secondary Key : none
   Sorting / Primary Subtotal : Disabled
   Sorting / Primary Subtotal for Date Key : none
   General / Add options summary : always
   General / Table for Exporting : Enabled
   Display / Totals : Disabled
   Display / Amount : single
   Display / Other Account Name : Disabled
   Display / Account Name : Enabled
   Display / Notes : Disabled
   Display / Memo : Disabled
   Display / Num : Disabled
   Accounts / Accounts : Bank

 Date   Description AccountAmount
   01/03/23 $103 income Root.Asset.Bank [1]$103.00
   01/09/23 $109 income Root.Asset.Bank [2]$109.00
   01/15/23 $22 expense Root.Asset.Bank [3]-$22.00
   02/03/23 $103 income Root.Asset.Bank [4]$103.00
   02/09/23 $109 income Root.Asset.Bank [5]$109.00
   02/15/23 $22 expense Root.Asset.Bank [6]-$22.00
   03/03/23 $103 income Root.Asset.Bank [7]$103.00
   03/09/23 $109 income Root.Asset.Bank [8]$109.00
   03/15/23 $22 expense Root.Asset.Bank [9]-$22.00
   04/03/23 $103 income Root.Asset.Bank [10]$103.00
   04/09/23 $109 income Root.Asset.Bank [11]$109.00
   04/15/23 $22 expense Root.Asset.Bank [12]-$22.00
   05/03/23 $103 income Root.Asset.Bank [13]$103.00
   05/09/23 $109 income Root.Asset.Bank [14]$109.00
   05/15/23 $22 expense Root.Asset.Bank [15]-$22.00
   06/03/23 $103 income Root.Asset.Bank [16]$103.00
   06/09/23 $109 income Root.Asset.Bank [17]$109.00
   06/15/23 $22 expense Root.Asset.Bank [18]-$22.00
   07/03/23 $103 income Root.Asset.Bank [19]$103.00
   07/09/23 $109 income Root.Asset.Bank [20]$109.00
   07/15/23 $22 expense Root.Asset.Bank [21]-$22.00
   08/03/23 $103 income Root.Asset.Bank [22]$103.00
   08/09/23 $109 income Root.Asset.Bank [23]$109.00
   08/15/23 $22 expense Root.Asset.Bank [24]-$22.00
   09/03/23 $103 income Root.Asset.Bank [25]$103.00
   09/09/23 $109 income Root.Asset.Bank [26]$109.00
   09/15/23 $22 expense Root.Asset.Bank [27]-$22.00
   10/03/23 $103 income Root.Asset.Bank [28]$103.00
   10/09/23 $109 income Root.Asset.Bank [29]$109.00
   10/15/23 $22 expense Root.Asset.Bank [30]-$22.00
   11/03/23 $103 income Root.Asset.Bank [31]$103.00
   11/09/23 $109 income Root.Asset.Bank [32]$109.00
   11/15/23 $22 expense Root.Asset.Bank [33]-$22.00
   12/03/23 $103 income Root.Asset.Bank [34]$103.00
   12/09/23 $109 income Root.Asset.Bank [35]$109.00
   12/15/23 $22 expense Root.Asset.Bank [36]-$22.00

References

   1. gnc-register:split-guid=859032c8639e49b49501e9a0a1497ac5
   2. gnc-register:split-guid=cbe4ba7904514285a22913f3d41fde9d
   3. gnc-register:split-guid=fd07c28587454d1896ac3d90b491abc7
   4. gnc-register:split-guid=8d2376b51564402b826965433604
   5. gnc-register:split-guid=ea146a234ff742649b93b9a33fefae2e
   6. gnc-register:split-guid=8ab91494621f4bf1b0cdfc5601359459
   7. gnc-register:split-guid=0b489080220c436aae8614023054953d
   8. gnc-register:split-guid=7a94654477ec47a2a63093d34236ea1f
   9. gnc-register:split-guid=66c9c5bbdf514ba7b20f06eda93e0eeb
  10. gnc-register:split-guid=c83755eb16374818807ce38e796be8d4
  11. gnc-register:split-guid=eb2ce4371dae4116abf8e69f8b3af6f6
  12. gnc-register:split-guid=df341fa54f054d128abdee4340448305
  13. 

Re: Simple list of key-value pairs?

2021-07-08 Thread Christopher Lam
IMO quotes and quasiquotes are being used perfectly well. You can use
'(system #f). However I suspect building a list of intermediate strings is
not desirable. And we may want to eliminate map and filter. How about
building the query-string piecemeal then building the final string once?

  (define (build-query-string)
(let lp ((query (or query '())) (acc '()))
  (match query
(() (string-concatenate acc))
(((_ #f) . rest) (lp rest acc))
(((name val) . rest)
 (lp rest (cons* name "="
 (if (string? val) val (object->string val))
 (if (null? acc) "" "&")
 acc))

On Thu, 8 Jul 2021 at 14:37, Hartmut Goebel 
wrote:

> Hi,
>
> I'm seeking advice for passing simple key-value pairs to a function and
> generate a string out of these values. Neither the names not the number
> of keys is known in advance.
>
> Background: This shall become a generic function for generating URI
> query-strings.
>
> My current approach please see below. Anyhow, I'm wondering whether the
> quite and quasiquote can be replaced by something simpler.
>
> (use-modules (ice-9 match))
>
> (define limit 100)
> (define evaluation "linux")
>
> (define* (api-uri base path #:rest query)
>
>(define (build-query-string kv)
>  (match kv
> ((name #f) #f)
> ((name (? string? value))
>  (string-append name "=" value))  ; FIXME: encode
> ((name (? number? value))
>  (string-append name "=" (number->string value)
>
>
>(format #t "~%Query: ~a~%~%" query)
>(let ((query-string
>   (when query
> (string-join
>  (filter (lambda (x) x) (map build-query-string query))
>  "&"
>  (format #t "~%Query-String: ~a~%~%" query-string)
>  ;; todo: build uri incl. query-string
>))
>
>
> (api-uri "https://ci.guix.gnu.org; "/api/jobs")
> (api-uri "https://ci.guix.gnu.org; "/api/jobs"
>   `("nr" ,limit)
>   `("evaluation" ,evaluation)
>   `("system" ,#f))
>
> --
> Regards
> Hartmut Goebel
>
> | Hartmut Goebel  | h.goe...@crazy-compilers.com   |
> | www.crazy-compilers.com | compilers which you thought are impossible |
>
>
>


Re: guile style

2021-06-19 Thread Christopher Lam
Agree set! is not a desirable form. It is not consistently optimisable. I
cannot find the reference in the manual.

Also consider the first form: you're building a list in 3 passes -- call
iota to generate a list, call filter to navigate the list again, then fold
to accumulate your answer. Therefore it's O(3N).

The preferred form is definitely from the little schemer.

On Sat, 19 Jun 2021, 8:56 am jerry,  wrote:

> I am fairly new to guile and scheme. People tell me that I should use a
> functional style.
>
> I have 3 solutions for project euler problem #1. The first is
> functional, the second is imperative and the third is written in "Little
> Schemer" style.
>
> I was hoping other guile users would comment on preferences or the
> "correct way". Sorry in advance for any wrapping problems that may occur.
>
> #!/usr/local/bin/guile  -s
> !#
> (use-modules (srfi srfi-1) (jpd stdio)) ;; for folds
> (define N 1000)
>
> (define ans
>(fold + 0
>  (filter
>(lambda (x) (or (= 0 (modulo x 3)) (= 0 (modulo x 5
>(iota N
> (print ans)
>
> (define ans 0)
> (for i N
>(if (or (= 0 (modulo i 3)) (= 0 (modulo i 5))) (set! ans (+ ans i
> (print ans)
>
> (define ans
>(let loop ((i 1) (ans 0))
>  (cond
>((>= i N) ans)
>((or (= 0 (modulo i 3)) (= 0 (modulo i 5))) (loop (1+ i) (+ ans i)))
>(else (loop (1+ i) ans)) )))
>
>


Re: Unbound variable warning/exception

2020-12-20 Thread Christopher Lam
The exception printer would be a good one to upgrade.

The dilemma is whether to search available modules in the current
repository, or in the whole of core guile. Do we want to show e.g. "Unbound
variable: vector-for-each. Did you forget (use-modules (srfi srfi-43))" ?

On Sun, 20 Dec 2020 at 21:36, Ludovic Courtès  wrote:

> Hi,
>
> Aleix Conchillo Flaqué  skribis:
>
> > On Fri, Dec 18, 2020 at 5:26 PM Christopher Lam
> >  wrote:
> >>
> >> Hi guilers, I saw in guix the incredibly useful unbound-variable
> exception
> >> printer written by Ludovic. I've adapted for use in gnucash as
> >> https://github.com/Gnucash/gnucash/commit/6f951784 -- there are now in
> >> guile 3.0.4 many more unbound-var warnings than in 3.0.2 -- wouldn't it
> be
> >> a useful hint to add to the warning in core guile as well?
> >
> > Wow, this is great!
> >
> > This should definitely be added to guile by default.
>
> In Guix, the hint is displayed by an 'unbound-variable exception
> handler, not by the 'unbound-variable printer; I think doing it in the
> printer could be confusing.
>
> Perhaps what could be done is export an 'unbound-variable handler that
> does all this, and have the REPL use it?
>
> Thanks,
> Ludo’.
>
>
>


Re: vector-last / vector-ref with negative indices?

2020-12-20 Thread Christopher Lam
Easy - vector-ref with a negative index is not defined in r[5|7]rs.

On Sun, 20 Dec 2020 at 06:59, Aleix Conchillo Flaqué 
wrote:

> Hi,
>
> This month I'm trying to go through Advent Of Code one more year
> (previous years I didn't get too far) and I've been finding myself
> writing the same patterns multiple times that could be avoided by just
> having a helper function.
>
> One of them is getting the last element of a vector. It is a quite
> common operation when solving these types of problems. For example
> Python as you might know uses negative indices.
>
> I have looked around and haven't seen it (unless I completely missed
> it which would be shameful) but wouldn't it be good to have this
> built-in by default?
>
> Instead of having to write:
>
> (vector-ref v (- (vector-length v) 1))
>
> you would write:
>
> (vector-last v) or even better (vector-ref v -1).
>
> Interestingly Racket doesn't offer those functions either as far as I can
> tell.
>
> Basic use case? Get the maximum element of a sorted vector which would
> be done in constant time.
>
> I'm trying to solve the problems idiomatically, to the best of my
> limited knowledge, with Scheme. It is possible that the times I'm
> using vectors I should think about it differently and not use them,
> but I'm not 100% sure.
>
> What am I missing?
>
> Thank you in advance,
>
> Aleix
>
>


Re: Unbound variable warning/exception

2020-12-19 Thread Christopher Lam
You can remove these "possibly unbound variable" warning by using modules
appropriately. It's not easy and tedious but necessary to achieve better
module hygiene.

See changes in https://github.com/Gnucash/gnucash/pull/831

On Sat, 19 Dec 2020, 6:08 pm Massimiliano Gubinelli, 
wrote:

> Hi all,
>
> nice piece of code!
>
> About these "possible unbounded variable" warnings, I have for GNU TeXmacs
> the opposite need: how can I turn them off? :)
>
> I was also curious to ask: which are currently the major applications of
> GNU Guile (as extension language)? For example, in TeXmacs we have ~110.000
> lines of scheme (still Guile 1.8).  I wanted to give a look around to
> understand what are good design patterns to use Guile 2+ as extension
> language.
>
> Best,
> Massimiliano
>
> > On 19. Dec 2020, at 02:46, Aleix Conchillo Flaqué 
> wrote:
> >
> > On Fri, Dec 18, 2020 at 5:26 PM Christopher Lam
> >  wrote:
> >>
> >> Hi guilers, I saw in guix the incredibly useful unbound-variable
> exception
> >> printer written by Ludovic. I've adapted for use in gnucash as
> >> https://github.com/Gnucash/gnucash/commit/6f951784 -- there are now in
> >> guile 3.0.4 many more unbound-var warnings than in 3.0.2 -- wouldn't it
> be
> >> a useful hint to add to the warning in core guile as well?
> >
> > Wow, this is great!
> >
> > This should definitely be added to guile by default.
> >
> > Aleix
> >
>
>


Unbound variable warning/exception

2020-12-18 Thread Christopher Lam
Hi guilers, I saw in guix the incredibly useful unbound-variable exception
printer written by Ludovic. I've adapted for use in gnucash as
https://github.com/Gnucash/gnucash/commit/6f951784 -- there are now in
guile 3.0.4 many more unbound-var warnings than in 3.0.2 -- wouldn't it be
a useful hint to add to the warning in core guile as well?


Re: No Guile on Windows? (was: My Guile Hacker Handbook)

2020-07-27 Thread Christopher Lam
My mistake: gnucash uses MinGW-w64.

The gnucash lead developer has a few patches to successfully compile guile
on MinGW-w64. It would be great if these patches were taken upstream and a
CI pipeline enabled for testing. Otherwise gnucash for windows will always
need to catch up, and is at severe risk of falling behind.

https://github.com/jralls/guile

On Sat, 25 Jul 2020, 10:28 pm Eli Zaretskii,  wrote:

> > From: Christopher Lam 
> > Date: Sat, 25 Jul 2020 13:56:28 +
> > Cc: guile-user , help-g...@gnu.org
> >
> > Gnucash 4.0 in windows is successfully using libguile-2.2-1.dll from
> MSYS2.
>
> Is Gnucash a MinGW build or an MSYS2 build?  If the latter, it's
> expected.
>


Re: No Guile on Windows? (was: My Guile Hacker Handbook)

2020-07-25 Thread Christopher Lam
Gnucash 4.0 in windows is successfully using libguile-2.2-1.dll from MSYS2.

On Sat, 25 Jul 2020 at 06:32, Eli Zaretskii  wrote:

> > Date: Sat, 25 Jul 2020 00:48:35 -0300
> > From: David Pirotte 
> > Cc: Dmitry Alexandrov , guile-user@gnu.org,
> help-g...@gnu.org
> >
> > fwiw, i've used msys2 (not so much anymore, but i still would if i had
> > to ...), easy to install, update, well maintained, very friendly on irc
> > when i needed to ask for help ...:
> >
> >   https://www.msys2.org/
> >
> > it has guile-2.2.7-1, threaded (which I've used. it works ...)
>
> AFAIU, that's not a native Windows port, that's an MSYS2 port, which
> is almost the same as a Cygwin build (MSYS2 is a fork of Cygwin).
>
> IOW, you cannot link the MSYS2 libguile with a native MinGW program,
> such as GDB or Gnu Make (or Lilypond, or any other application
> mentioned in this thread).  Right?
>
>


Re: No Guile on Windows? (was: My Guile Hacker Handbook)

2020-07-24 Thread Christopher Lam
Ditto gnucash on windows does include guile 2.2 but it's a major pain point
to get it to build.

https://code.gnucash.org/logs/2020/07/16.html#T20:20:40

On Fri, 24 Jul 2020, 3:24 pm Dr. Arne Babenhauserheide, 
wrote:

>
> Eli Zaretskii  writes:
> > 
> > Sadly, Guile seems to care only about one OS: GNU/Linux, and more or
> > less disregard the rest.  Features are added that clearly cannot
> > easily work on other OSes, let alone non-Posix ones, and with each
> > such new feature producing a working MinGW port becomes harder and
> > harder, even for experienced hackers.
>
> This is one of the biggest worries I have with the time I put into
> Guile: Many of my friends are still on Windows and in the current state
> of Guile I won’t be able to create tools that help them.
>
> Creating installers for Windows was bad with Python, it is much worse
> with Guile. I wish I could just do something like
> guild package --target windows -o my-program.exe entry-point.scm
>
> This prevents people from using Guile for anything that might have to be
> cross-platform (though the Lilypond folks got it working
> https://lilypond.org/windows.de.html).
>
> > Please don't bother replying to this rant, it's just FYI, to convey my
> > personal recollections and experiences from doing the 2.0.x port, and
> > I don't intend to argue about it.
> > 
>
> I replied, because I did not intend to argue but rather support your
> point. While Guile is easiest to use on GNU Linux, a Windows port is a
> hard requirement if we want Guile to be useful as a platform for writing
> programs. There is GTK for Windows and it would be nice if we could
> actually script it from Guile:
> https://www.gtk.org/docs/installations/windows/
>
> Best wishes,
> Arne
> --
> Unpolitisch sein
> heißt politisch sein
> ohne es zu merken
>


Re: srfi-9 vs make-record-type

2020-07-13 Thread Christopher Lam
Followup.
As part of preparation for compatibility with guile-3, we've changed
gnucash's use of make-record-type to define-record-type.
Since the record field getters and setters are not exportable across
modules, we've used the following forms.

(define-record-type :record
 (make-record field1 field2)
 record?
 (field1 field1-getter field1-setter)
 (field2 field2-getter field2-setter))
(define-public gnc:field1-getter field1-getter)
(define-public gnc:field1-setter field1-setter)
(define-public gnc:field2-getter field2-getter)
(define-public gnc:field2-setter field2-setter)

There may be a more elegant solution but for now it'll do. See the set of
related commits at
https://github.com/Gnucash/gnucash/commits?after=00bbd32677fba00ae0e709dce0bb35e06f90305c+4
onwards.

On Mon, 26 Aug 2019 at 12:20, Christopher Lam 
wrote:

> Thank you Mark and John.
>
> On Mon, 5 Aug 2019 at 18:18, Mark H Weaver  wrote:
>
>> The problem here is that 'make-person' is a macro.  Macros are expanded
>> at compile time, and must therefore be available at compile time.
>>
>> When you compile 'm2.scm', those macros are not available, because
>> 'load' only has effects at run-time, by design.  Since there is no macro
>> definition for 'make-person' at compile-time, Guile's compiler generates
>> code that assumes it will be a procedure.
>>
>> In summary, you cannot use 'load' to import macros from another module.
>>
>> > For various reasons I must keep (load "module.scm") mechanism
>> If you can share those reasons, perhaps I can help you find another
>> solution.
>>
>
> The only reason is that I've started cleaning up numerous modules in
> GnuCash written about 20 years ago, and the hyper-modular approach is too
> difficult to try unravel for now. So, I've converted records to srfi-9
> wherever possible (i.e. used internally), and left the exported ones alone.
> This one was a fun one to fix:
> https://github.com/Gnucash/gnucash/commit/e3a695d0 ;-)
>


Re: "Missing" libraries/concepts found in other languages/ecosystems?

2020-07-10 Thread Christopher Lam
With respect to looking for guile examples, I've seen examples whereby
LISPers would run some code, dynamically changing the code while running in
production, and immediately the new code would be replaced in-memory. Not
sure if this is possible in scheme. Any live pointers would be appreciated
:)

On Wed, 8 Jul 2020 at 07:38, Simen Endsjø  wrote:

>
> Hi, I'm new to scheme/lisp, so I'm trying to find out how to do
> things the "lisp
> way". On the other hand, I like things from other ecosystems too,
> and I'm having
> problems finding this for Guile. It might be because there's no
> need for it/I'm
> terrible at searching/nobody had the time yet, or something else.
>
> I've been trying to find implementations for https://reactivex.io
> without any
> luck. And I'm unable to find implementation of FP concepts as
> found in Haskell
> and other languages. Functor, Monad, lenses (and other helpers for
> working with
> immutable data).
>
> Does things like this exists, or is it better to use something
> else?
>
> Regards Simen
>


gettext uses scm_from_locale_string instead of scm_from_utf8_string

2020-06-08 Thread Christopher Lam
Not sure if this is a design issue, but the subject explains it causes
problems in use. Hence the following fix is needed and GnuCash can't use
gettext.

https://bugs.gnucash.org/show_bug.cgi?id=797746
https://github.com/Gnucash/gnucash/commit/b5aeca94b


Re: Happy birthday, Guile!

2020-02-18 Thread Christopher Lam
A bit late, and perhaps not as sophisticated as some bigger modules here.

Two functions defined as follows: nested-alist-set! nested-alist-get at
https://github.com/Gnucash/gnucash/blob/1f83cfaf64d1cd3c8862b427dd043154f780a772/gnucash/report/html-chart.scm#L37

Consider a nested alist describing unix file system
(define lst
 (list
  (cons 'usr (list
  (cons 'bin "binary files")
  (cons 'games "g4m3s")
  (cons 'include (list
  (cons 'guile (list
(cons '2.2 "old")))
  (cons 'linux "da best")))

We can access a leaf node via (nested-alist-get lst '(usr include linux))
--> "da best", and set a leaf node via (nested-alist-set! lst '(usr include
python) "boo"). This is probably easy to seasoned schemers, but still a
nice pair of functions to use in modifying nested alists before conversion
into json.

On Mon, 17 Feb 2020 at 09:16, Ludovic Courtès  wrote:

> Hi!
>
> Ricardo Wurmus  skribis:
>
> > What do you think about adding these things to
> > https://notabug.org/cwebber/guile-webutils/ ?  This was once intended to
> > be a collection of useful tools that come in handy when writing web
> > applications.
>
> I didn’t know about guile-webutils but consolidating Web tools in this
> package sounds like a great idea!
>
> Ludo’.
>
>


Re: Pure (side-effect-free) calls into c/c++?

2020-01-11 Thread Christopher Lam
I can add a contribution! The good thing about memoize is it's simple to
create. You forgot a catch however: if the memoized return-val is #f then
your memoizer https://hg.sr.ht/~bjoli/misc/browse/default/memoize.scm will
not recognise that #f is a valid cached return-val and will call the lambda
again. (FWIW I shudder think what a *fast* memoizer would do).

Here's how I did mine:

(define (memoize f)
  (let ((h (make-hash-table)))
(lambda args
  (cond
   ((hash-ref h args) => car)
   (else (let ((res (apply f args)))
   (hash-set! h args (list res))
   res))

(define-syntax-rule (lambda/macro args body ...)
  (memoize (lambda args body ...)))

(define-syntax-rule (define/macro (f . args) body ...)
  (define f lambda/macro args body ...))



On Sat, 11 Jan 2020 at 17:40, Linus Björnstam 
wrote:

> I have a macro called lambda/memo and define/memo for these situations:
> https://hg.sr.ht/~bjoli/misc/browse/default/memoize.scm
>
> If the function gets called with a gazillion different arguments the
> memoizatiin hash gets large, and there are no mechanisms to stop that from
> happening. It also lacks a fast path for single argument functions.
>
> You can disregard the repo license. Use that function is you like, if you
> like to.
>
>
> --
>   Linus Björnstam
>
> On Fri, 10 Jan 2020, at 23:36, Linas Vepstas wrote:
> > So, I've got lots of C code wrapped up in guile, and I'd like to declare
> > many of these functions to be pure functions, side-effect-free, thus
> > hopefully garnering some optimizations.  Is this possible? How would I do
> > it? A cursory google-search reveals no clues.
> >
> > To recap, I've got functions f and g that call into c++, but are pure
> (i.e.
> > always return the same value for the same arguments).   I've got
> > user-written code that looks like this:
> >
> > (define (foo x)
> > (g  (f 42) (f x) (f 43))
> >
> > and from what I can tell, `f` is getting called three times whenever the
> > user calls `foo`. I could tell the user to re-write their code to cache,
> > manually: viz:
> >
> > (define c42 (f 42))
> > (define c43 (f 43))
> > (define (foo x) (g c42 (f x) c43))
> >
> > but asking the users to do this is .. cumbersome.  And barely worth it:
> `f`
> > takes under maybe 10 microseconds to run; so most simple-minded caching
> > stunts don't pay off. But since `foo` is called millions/billions of
> times,
> > I'm motivated to find something spiffy.
> >
> > Ideas? suggestions?
> >
> > -- Linas
> > --
> > cassette tapes - analog TV - film cameras - you
> >
>
>


Re: a C<->guile O(2N) problem

2019-12-11 Thread Christopher Lam
Update: the solution turned out to be easy to do in swig, and actually not
that useful. Prepend-and-reverse to convert g_list to SCM list, for lists
tested up to 10e6, takes a fraction of a second.

https://github.com/Gnucash/gnucash/pull/620 was the proof-of-concept O(1)
GList->SplitListNode with benchmarks.


On Sun, 8 Dec 2019 at 13:15, Christopher Lam 
wrote:

> Hello guilers
>
> I am asking for some help optimizing C<->guile while working on the
> simplest of lispy data structures; the proper list. The C equivalent being
> used is glib's g_list.
>
> In
> https://github.com/Gnucash/gnucash/blob/maint/common/base-typemaps.i#L142
> these are converted via the simple but O(2*N) expensive
> prepend-and-reverse, building SCM list by traversing g_list, and vice versa
> for the return trip.
>
> It came to light that if we could define the GList transform with CAR =
> node->data and CDR = node->next; the C->SCM transform could be O(1)
> efficient. There are issues about finding the correct SWIG converter for
> node->data pointer dereferences, but this is a problem for another day.
> With SCM->C transform, we don't anticipate long lists, so, the issue is
> less acute, but it would be nice to optimise it too.
>
> Does anyone have experience converting the above efficiently? Is this
> something that would need ffi work?
>
> Thanks for any help!
>


a C<->guile O(2N) problem

2019-12-08 Thread Christopher Lam
Hello guilers

I am asking for some help optimizing C<->guile while working on the
simplest of lispy data structures; the proper list. The C equivalent being
used is glib's g_list.

In https://github.com/Gnucash/gnucash/blob/maint/common/base-typemaps.i#L142
these are converted via the simple but O(2*N) expensive
prepend-and-reverse, building SCM list by traversing g_list, and vice versa
for the return trip.

It came to light that if we could define the GList transform with CAR =
node->data and CDR = node->next; the C->SCM transform could be O(1)
efficient. There are issues about finding the correct SWIG converter for
node->data pointer dereferences, but this is a problem for another day.
With SCM->C transform, we don't anticipate long lists, so, the issue is
less acute, but it would be nice to optimise it too.

Does anyone have experience converting the above efficiently? Is this
something that would need ffi work?

Thanks for any help!


Re: Interactive Debugging

2019-10-23 Thread Christopher Lam
Agree it'll be a major aid to decreasing the learning curve. For now the
only way to analyse a variable in a script is to (pk) it, which is annoying
when it's a record/alist etc. Need to refine the pk several times or write
a custom printer.

Not sure how much knowledge of debugger is required, all I want to do is to
dump local variables at the breakpoint.

On Sat, 19 Oct 2019, 05:23 Mark H Weaver,  wrote:

> "Thompson, David"  writes:
>
> > On Fri, Oct 18, 2019 at 8:40 AM Matt Wette  wrote:
> >>
> >> On 10/17/19 9:39 PM, Christopher Howard wrote:
> >> > Hi, it seems like with the flexibility of Guile, I should be able to
> do
> >> > something like this:
> >> > ```(define (foo)  (let ((a 1)(b 2)(c 3))
> (jump-into-
> >> > debugging-repl)))```
> >> > And have access to a, b, and c and their values. But I'm not quite
> >> > figuring out how to this.
> >> >
> >>
> >> Define dump-into-debugging-repl as
> >>
> >> (start-repl #:debug (make-debug (stack->vector (make-stack #t)) 0
> >> "trap!" #t))
> >
> > I think something like this should be shipped in the (system repl
> > debug) module.  I'm used to quick and easy access to a debugger in
> > other languages, such as Ruby, and having to wrap your head around the
> > REPL, debug, and stack code is too much to ask of any new Guiler.
>
> For what it's worth, I think something like this would be a welcome
> addition.  However, my knowledge of the Guile debugger is currently
> quite weak, so I'd prefer to hear from Andy before proceeding.
>
>  Thanks,
>Mark
>
>


Re: srfi-9 vs make-record-type

2019-08-26 Thread Christopher Lam
Thank you Mark and John.

On Mon, 5 Aug 2019 at 18:18, Mark H Weaver  wrote:

> The problem here is that 'make-person' is a macro.  Macros are expanded
> at compile time, and must therefore be available at compile time.
>
> When you compile 'm2.scm', those macros are not available, because
> 'load' only has effects at run-time, by design.  Since there is no macro
> definition for 'make-person' at compile-time, Guile's compiler generates
> code that assumes it will be a procedure.
>
> In summary, you cannot use 'load' to import macros from another module.
>
> > For various reasons I must keep (load "module.scm") mechanism
> If you can share those reasons, perhaps I can help you find another
> solution.
>

The only reason is that I've started cleaning up numerous modules in
GnuCash written about 20 years ago, and the hyper-modular approach is too
difficult to try unravel for now. So, I've converted records to srfi-9
wherever possible (i.e. used internally), and left the exported ones alone.
This one was a fun one to fix:
https://github.com/Gnucash/gnucash/commit/e3a695d0 ;-)


srfi-9 vs make-record-type

2019-07-21 Thread Christopher Lam
Hi All
In experiments converting legacy code to use srfi-9 records, I'm finding
the latter doesn't travel well across modules.

See simple code below -- m1.scm runs fine however m2.scm borks when
creating srfi-9 record object

Any clue why srfi-9 can't be exported?

For various reasons I must keep (load "module.scm") mechanism
m1.scm follows
(use-modules (srfi srfi-9))

(define-record-type 
  (make-person name age)
  person?
  (name person-name set-person-name!)
  (age person-age set-person-age!))

(define  (make-record-type "pet" '(name age)))
(define make-pet (record-constructor ))
(define pet? (record-predicate ))
(define pet-name (record-accessor  'name))
(define pet-age (record-accessor  'age))
(define set-pet-name! (record-modifier  'name))
(define set-pet-age! (record-modifier  'age))
(export make-person)
(export make-pet)

(display "pet ")
(let ((pet2 (make-pet "milou" 7)))
  (display (pet-name pet2)))
(display ", person ")
(let ((person2 (make-person "james" 54)))
  (display (person-name person2)))
(newline)
m2.scm follows
(load "m1.scm")
(display "in m2:")
(newline)
(display "pet ")
(let ((pet2 (make-pet "milou" 7)))
  (display (pet-name pet2)))
(display ", person ")
(let ((person2 (make-person "james" 54)))
  (display (person-name person2)))
(newline)

$guile m1.scm runs successfully

pet milou, person james

$guile m2.scm first runs m1.scm but fails to recognise the srfi-9
make-person exists:
pet milou, person james
in m2:
pet milou, person Backtrace:
   6 (apply-smob/1 #)
In ice-9/boot-9.scm:
705:2  5 (call-with-prompt _ _ #)
In ice-9/eval.scm:
619:8  4 (_ #(#(#)))
In ice-9/boot-9.scm:
   2312:4  3 (save-module-excursion _)
  3831:12  2 (_)
In /home/chris/sources/caca/m2.scm:
 8:15  1 (_)
In unknown file:
   0 (_ "james" 54)

ERROR: Wrong type to apply: #


Re: string-ports issue on Windows

2019-05-26 Thread Christopher Lam
Addendum - wish to confirm if guile bug (guile-2.2 on Windows):
- set locale to non-Anglo so that (setlocale LC_ALL) returns
"French_France.1252"
- call (strftime "%B" 400) - that's 4x10^6 -- this should return
"février 1970"

but the following error arises:
Throw to key `decoding-error' with args `("scm_from_utf8_stringn" "input
locale conversion error" 0 #vu8(102 233 118 114 105 101 114 32 49 57 55
48))'.

Is this a bug?

On Tue, 14 May 2019 at 12:42, Christopher Lam 
wrote:

> Hi Mark
> Final update - first, we've reused your efficient substring-replace
> function in
> https://github.com/Gnucash/gnucash/commit/7d15e6e4e727c87fb4a501e924c4ae02276e508d
> from a few years ago.
> Second, the email thread
> https://lists.gnu.org/archive/html/guile-devel/2014-03/msg00060.html
> confirmed a lot of issues in guile-2.0 could be solved in Windows by
> upgrading to guile-2.2. So, GnuCash has now upgraded to guile-2.2 on
> Windows and the string-ports are now behaving.
> Thank you (twice)
> :)
>
> On Fri, 19 Apr 2019 at 10:26, Christopher Lam 
> wrote:
>
>> Hi,
>> The patch *does* work and handles unicode properly :) There are
>> unintended consequences however, whereby other (probably C-based)
>> string-code in Windows are now reading the lira-symbol into unexpected
>> chars (eg lira-symbol -> "â‚°" i.e. #xe2 #x201a #xba) but this is now
>> outside the scope of this post.
>> Thank you again!
>>
>> On Thu, 18 Apr 2019 at 21:20, Mark H Weaver  wrote:
>>
>>> Hi again,
>>>
>>> Earlier, I wrote:
>>>
>>> > Christopher Lam  writes:
>>> >
>>> >> Hi Mark
>>> >> Thank you so much for looking into this.
>>> >> I'm reviewing the GnuCash for Windows package (v3.5 released April
>>> 2019)
>>> >> which contains the following libraries:
>>> >> - guile 2.0.14
>>> >
>>> > Ah, for some reason I thought you were using Guile 2.2.  That explains
>>> > the problem.
>>> >
>>> > In Guile 2.0, string ports internally used the locale encoding by
>>> > default, which meant that any characters not supported by the locale
>>> > encoding would be munged.
>>> >
>>> > Guile 2.2 changed the behavior of string ports to always use UTF-8
>>> > internally, which ensures that all valid Guile strings can pass through
>>> > unmunged.
>>> >
>>> > So, this problem would almost certainly be fixed by updating to
>>> > Guile 2.2.
>>>
>>> It's probably a good idea to update to Guile 2.2 anyway, but I'd like to
>>> also offer the following workaround, which monkey patches the string
>>> port procedures in Guile 2.0 to behave more like Guile 2.2.
>>>
>>> Note that it only patches the Scheme APIs for string ports, and not the
>>> underlying C functions.  It might be that some code, possibly within
>>> Guile itself, creates a string port using the C functions, and such
>>> string ports may still munge characters.
>>>
>>> Anyway, if you want to try it, arrange for GnuCash to evaluate the code
>>> below, after initializing Guile.
>>>
>>>   Mark
>>>
>>>
>>> (when (string=? (effective-version) "2.0")
>>>   ;; When using Guile 2.0.x, use monkey patching to change the
>>>   ;; behavior of string ports to use UTF-8 as the internal encoding.
>>>   ;; Note that this is the default behavior in Guile 2.2 or later.
>>>   (let* ((mod (resolve-module '(guile)))
>>>  (orig-open-input-string  (module-ref mod 'open-input-string))
>>>  (orig-open-output-string (module-ref mod 'open-output-string))
>>>  (orig-object->string (module-ref mod 'object->string))
>>>  (orig-simple-format  (module-ref mod 'simple-format)))
>>>
>>> (define (open-input-string str)
>>>   (with-fluids ((%default-port-encoding "UTF-8"))
>>> (orig-open-input-string str)))
>>>
>>> (define (open-output-string)
>>>   (with-fluids ((%default-port-encoding "UTF-8"))
>>> (orig-open-output-string)))
>>>
>>> (define (object->string . args)
>>>   (with-fluids ((%default-port-encoding "UTF-8"))
>>> (apply orig-object->string args)))
>>>
>>> (define (simple-format . args)
>>>   (with-fluids ((%default-port-encoding "UTF-8"))
>>> (apply orig-simple-format args)))
>>>
>>> (define (call-with-input-string str proc)
>>>   (proc (open-input-string str)))
>>>
>>> (define (call-with-output-string proc)
>>>   (let ((port (open-output-string)))
>>> (proc port)
>>> (get-output-string port)))
>>>
>>> (module-set! mod 'open-input-string   open-input-string)
>>> (module-set! mod 'open-output-string  open-output-string)
>>> (module-set! mod 'object->string  object->string)
>>> (module-set! mod 'simple-format   simple-format)
>>> (module-set! mod 'call-with-input-string  call-with-input-string)
>>> (module-set! mod 'call-with-output-string call-with-output-string)
>>>
>>> (when (eqv? (module-ref mod 'format) orig-simple-format)
>>>   (module-set! mod 'format simple-format
>>>
>>


Re: string-ports issue on Windows

2019-05-13 Thread Christopher Lam
Hi Mark
Final update - first, we've reused your efficient substring-replace
function in
https://github.com/Gnucash/gnucash/commit/7d15e6e4e727c87fb4a501e924c4ae02276e508d
from a few years ago.
Second, the email thread
https://lists.gnu.org/archive/html/guile-devel/2014-03/msg00060.html
confirmed a lot of issues in guile-2.0 could be solved in Windows by
upgrading to guile-2.2. So, GnuCash has now upgraded to guile-2.2 on
Windows and the string-ports are now behaving.
Thank you (twice)
:)

On Fri, 19 Apr 2019 at 10:26, Christopher Lam 
wrote:

> Hi,
> The patch *does* work and handles unicode properly :) There are unintended
> consequences however, whereby other (probably C-based) string-code in
> Windows are now reading the lira-symbol into unexpected chars (eg
> lira-symbol -> "â‚°" i.e. #xe2 #x201a #xba) but this is now outside the
> scope of this post.
> Thank you again!
>
> On Thu, 18 Apr 2019 at 21:20, Mark H Weaver  wrote:
>
>> Hi again,
>>
>> Earlier, I wrote:
>>
>> > Christopher Lam  writes:
>> >
>> >> Hi Mark
>> >> Thank you so much for looking into this.
>> >> I'm reviewing the GnuCash for Windows package (v3.5 released April
>> 2019)
>> >> which contains the following libraries:
>> >> - guile 2.0.14
>> >
>> > Ah, for some reason I thought you were using Guile 2.2.  That explains
>> > the problem.
>> >
>> > In Guile 2.0, string ports internally used the locale encoding by
>> > default, which meant that any characters not supported by the locale
>> > encoding would be munged.
>> >
>> > Guile 2.2 changed the behavior of string ports to always use UTF-8
>> > internally, which ensures that all valid Guile strings can pass through
>> > unmunged.
>> >
>> > So, this problem would almost certainly be fixed by updating to
>> > Guile 2.2.
>>
>> It's probably a good idea to update to Guile 2.2 anyway, but I'd like to
>> also offer the following workaround, which monkey patches the string
>> port procedures in Guile 2.0 to behave more like Guile 2.2.
>>
>> Note that it only patches the Scheme APIs for string ports, and not the
>> underlying C functions.  It might be that some code, possibly within
>> Guile itself, creates a string port using the C functions, and such
>> string ports may still munge characters.
>>
>> Anyway, if you want to try it, arrange for GnuCash to evaluate the code
>> below, after initializing Guile.
>>
>>   Mark
>>
>>
>> (when (string=? (effective-version) "2.0")
>>   ;; When using Guile 2.0.x, use monkey patching to change the
>>   ;; behavior of string ports to use UTF-8 as the internal encoding.
>>   ;; Note that this is the default behavior in Guile 2.2 or later.
>>   (let* ((mod (resolve-module '(guile)))
>>  (orig-open-input-string  (module-ref mod 'open-input-string))
>>  (orig-open-output-string (module-ref mod 'open-output-string))
>>  (orig-object->string (module-ref mod 'object->string))
>>  (orig-simple-format  (module-ref mod 'simple-format)))
>>
>> (define (open-input-string str)
>>   (with-fluids ((%default-port-encoding "UTF-8"))
>> (orig-open-input-string str)))
>>
>> (define (open-output-string)
>>   (with-fluids ((%default-port-encoding "UTF-8"))
>> (orig-open-output-string)))
>>
>> (define (object->string . args)
>>   (with-fluids ((%default-port-encoding "UTF-8"))
>> (apply orig-object->string args)))
>>
>> (define (simple-format . args)
>>   (with-fluids ((%default-port-encoding "UTF-8"))
>> (apply orig-simple-format args)))
>>
>> (define (call-with-input-string str proc)
>>   (proc (open-input-string str)))
>>
>> (define (call-with-output-string proc)
>>   (let ((port (open-output-string)))
>> (proc port)
>> (get-output-string port)))
>>
>> (module-set! mod 'open-input-string   open-input-string)
>> (module-set! mod 'open-output-string  open-output-string)
>> (module-set! mod 'object->string  object->string)
>> (module-set! mod 'simple-format   simple-format)
>> (module-set! mod 'call-with-input-string  call-with-input-string)
>> (module-set! mod 'call-with-output-string call-with-output-string)
>>
>> (when (eqv? (module-ref mod 'format) orig-simple-format)
>>   (module-set! mod 'format simple-format
>>
>


Re: string-ports issue on Windows

2019-04-19 Thread Christopher Lam
Hi,
The patch *does* work and handles unicode properly :) There are unintended
consequences however, whereby other (probably C-based) string-code in
Windows are now reading the lira-symbol into unexpected chars (eg
lira-symbol -> "â‚°" i.e. #xe2 #x201a #xba) but this is now outside the
scope of this post.
Thank you again!

On Thu, 18 Apr 2019 at 21:20, Mark H Weaver  wrote:

> Hi again,
>
> Earlier, I wrote:
>
> > Christopher Lam  writes:
> >
> >> Hi Mark
> >> Thank you so much for looking into this.
> >> I'm reviewing the GnuCash for Windows package (v3.5 released April 2019)
> >> which contains the following libraries:
> >> - guile 2.0.14
> >
> > Ah, for some reason I thought you were using Guile 2.2.  That explains
> > the problem.
> >
> > In Guile 2.0, string ports internally used the locale encoding by
> > default, which meant that any characters not supported by the locale
> > encoding would be munged.
> >
> > Guile 2.2 changed the behavior of string ports to always use UTF-8
> > internally, which ensures that all valid Guile strings can pass through
> > unmunged.
> >
> > So, this problem would almost certainly be fixed by updating to
> > Guile 2.2.
>
> It's probably a good idea to update to Guile 2.2 anyway, but I'd like to
> also offer the following workaround, which monkey patches the string
> port procedures in Guile 2.0 to behave more like Guile 2.2.
>
> Note that it only patches the Scheme APIs for string ports, and not the
> underlying C functions.  It might be that some code, possibly within
> Guile itself, creates a string port using the C functions, and such
> string ports may still munge characters.
>
> Anyway, if you want to try it, arrange for GnuCash to evaluate the code
> below, after initializing Guile.
>
>   Mark
>
>
> (when (string=? (effective-version) "2.0")
>   ;; When using Guile 2.0.x, use monkey patching to change the
>   ;; behavior of string ports to use UTF-8 as the internal encoding.
>   ;; Note that this is the default behavior in Guile 2.2 or later.
>   (let* ((mod (resolve-module '(guile)))
>  (orig-open-input-string  (module-ref mod 'open-input-string))
>  (orig-open-output-string (module-ref mod 'open-output-string))
>  (orig-object->string (module-ref mod 'object->string))
>  (orig-simple-format  (module-ref mod 'simple-format)))
>
> (define (open-input-string str)
>   (with-fluids ((%default-port-encoding "UTF-8"))
> (orig-open-input-string str)))
>
> (define (open-output-string)
>   (with-fluids ((%default-port-encoding "UTF-8"))
> (orig-open-output-string)))
>
> (define (object->string . args)
>   (with-fluids ((%default-port-encoding "UTF-8"))
> (apply orig-object->string args)))
>
> (define (simple-format . args)
>   (with-fluids ((%default-port-encoding "UTF-8"))
> (apply orig-simple-format args)))
>
> (define (call-with-input-string str proc)
>   (proc (open-input-string str)))
>
> (define (call-with-output-string proc)
>   (let ((port (open-output-string)))
> (proc port)
> (get-output-string port)))
>
> (module-set! mod 'open-input-string   open-input-string)
> (module-set! mod 'open-output-string  open-output-string)
> (module-set! mod 'object->string  object->string)
> (module-set! mod 'simple-format   simple-format)
> (module-set! mod 'call-with-input-string  call-with-input-string)
> (module-set! mod 'call-with-output-string call-with-output-string)
>
> (when (eqv? (module-ref mod 'format) orig-simple-format)
>   (module-set! mod 'format simple-format
>


Re: string-ports issue on Windows

2019-04-16 Thread Christopher Lam
Thank you Mark

The problem is rather obscure and may have been fixed in 2.2.

I've taken the reins of handling the guile code in GnuCash. For various
reasons I can't fathom, the Windows build includes Guile 2.0.14 rather than
Guile-2.2. I've checked NEWS and there was change in SRFI-6 string-ports to
make them Unicode-capable in 2.0.6.

Bearing in mind majority of strings code in GnuCash handle Unicode just
fine. However, there are some currencies e.g.TYR
https://en.wikipedia.org/wiki/Turkish_lira need extended Unicode and are
misprinted as ? in the reports.

I've dwelved down and figure there are only 2 offending functions. (format
#f "~a bla" str) and (with-output-to-string) as described above. After much
experimentation I can fix by changing (format) to (string-append), and
changing (with-ouput-to-string) to (open-string-port) and importing srfi-6
as described in original port, and these fix the TYR symbol display. Hence
my suspicion that string-ports on Windows munging Unicode. To try elucidate
this I've also tried removing (setlocale LC_ALL "") and dumping
(locale-encoding) which is "CP1252".

There are also other bits where UTF8 is being interpreted as CP1252 but
these are outside the scope of this post.

So, I'm rather late in this game (started diving into scheme 18 months ago)
and have probably missed many controversial changes in the past years, but
the issue above seems weird to me, why the Windows port is munging Unicode
:)

On Tue, 16 Apr 2019 at 17:29, Mark H Weaver  wrote:

> Hi Christopher,
>
> Christopher Lam  writes:
>
> > I'm struggling with string-ports on Windows.
> >
> > Last para of
> > https://www.gnu.org/software/guile/manual/html_node/String-Ports.html
> > "With string ports, the port-encoding is treated differently than other
> > types of ports. When string ports are created, they do not inherit a
> > character encoding from the current locale. They are given a default
> locale
> > that allows them to handle all valid string characters."
> >
> > This causes a string-sanitize function to not run correctly in Windows.
> > (locale-encoding) says "CP1252" no matter what LANG or setlocale I try.
> >
> > The use case is to sanitize string for html, but on Windows it munges
> > extended-unicode.
>
> Can you explain more fully what the problem is?  I know a fair amount
> about Unicode, but my knowledge of Windows is extremely weak.
>
> What exactly is "extended-unicode" in this context?  References welcome.
>
>   Thanks,
> Mark
>


string-ports issue on Windows

2019-04-15 Thread Christopher Lam
Dear All

I'm struggling with string-ports on Windows.

Last para of
https://www.gnu.org/software/guile/manual/html_node/String-Ports.html
"With string ports, the port-encoding is treated differently than other
types of ports. When string ports are created, they do not inherit a
character encoding from the current locale. They are given a default locale
that allows them to handle all valid string characters."

This causes a string-sanitize function to not run correctly in Windows.
(locale-encoding) says "CP1252" no matter what LANG or setlocale I try.

The use case is to sanitize string for html, but on Windows it munges
extended-unicode. So i've had to resort to this uglier code:
https://pastebin.com/raw/ys4QrhMh which does work, but raises the question
why we have to do it in the first place.

It means *any* string-ports must be avoided to avoid cross-platform string
issues, right? It's a shame because (format) is quite useful.

Chris


Re: SRFI 64: How do I create a test-runner stub

2019-03-07 Thread Christopher Lam
Hi

In gnucash I've resorted to writing my own srfi-64 test-runner. See the
entry point at (run-test-proper) at
https://github.com/Gnucash/gnucash/blob/maint/gnucash/report/standard-reports/test/test-transaction.scm

Its definition is at
https://github.com/Gnucash/gnucash/blob/maint/libgnucash/engine/test/srfi64
-extras.scm and takes care of both returning #f if any test fails, and also
doing an IMHO better job at logging tests.


On Thu, 7 Mar 2019 at 21:03, sirgazil  wrote:

> Hello,
>
> I'm trying to implement a procedure that takes a test-runner object and
> returns a string with information about the most recently run test. For
> example, calling
>
>(format-test-result (make-runner #:test-name "A is not B."
> #:result-kind 'fail))
>
> is expected to return:
>
>✖ FAIL A is not B.
>
> In the example, `make-runner` is a procedure that is supposed to create
> a test-runner stub with the given values, so that I can test the
> `format-test-result` procedure.
>
> I thought I could define `make-runner` body like this:
>
>(let ((runner-stub (test-runner-null)))
>  (test-runner-test-name! runner-stub test-name)
>  (test-result-set! runner-stub 'result-kind result-kind)
>  stub-runner))
>
> The problem is, the `test-runner-test-name!` setter does not exist. And
> test-runner objects don't seem to have a `test-name` slot. They do
> provide a `test-runner-test-name` getter, though.
>
> So I don't know how to create a test-runner stub to test my procedure.
>
> What would you do in this case?
>
>
> --
> Luis Felipe López Acevedo
> http://sirgazil.bitbucket.io/
>
>
>
>


Re: issues unit testing with srfi-64

2018-12-29 Thread Christopher Lam
Hi
In gnucash I've resorted to writing my own srfi-64 test-runner. See the
entry point at (run-test-proper) at
https://github.com/Gnucash/gnucash/blob/maint/gnucash/report/standard-reports/test/test-transaction.scm

Its definition is at
https://github.com/Gnucash/gnucash/blob/maint/libgnucash/engine/test/srfi64-extras.scm
and takes care of both returning #f if any test fails, and also doing an
IMHO better job at logging tests.

On Sun., 30 Dec. 2018, 08:05 Aleix Conchillo Flaqué  Hi!
>
> happy holidays and almost happy new year to everyone!
>
> I've added unit tests to guile-json and I have found a couple of
> issues. This is the branch:
>
> https://github.com/aconchillo/guile-json/tree/switch-to-alist-and-vectors
>
> First one (which might not be a real issue) is that (test-end) doesn't
> exit with an exit status different than 0 if a test fails. And this
> will cause automake to believe the tests passed when they actually did
> not. I have solved this with the following which works for my use
> case, but I'm not sure if that's the right way:
>...
>(test-end "test-builder")
>
>(exit (if (eqv? 0 (test-runner-fail-count (test-runner-current))) 0 1))
>
> (I could have returned the fail-count directly, but since there are
> only 255 exit values I thought it could wrap around.)
>
> The other issue is that the beginning of the log files are corrupted:
>
>  Starting test test-builder  (Writing full log to "test-builder.log")
> # of expected passes  19
> r.scm"
>   source-line: 33
>   source-form: (test-equal "1234" (scm->json-string 1234))
>
> This should be something like:
>
> Test begin:
>   source-file: "tests/test-builder.scm"
>   source-line: 33
>   source-form: (test-equal "1234" (scm->json-string 1234))
> Test end:
>   result-kind: pass
>   actual-value: "1234"
>   expected-value: "1234"
>
> I don't know how to fix this one yet.
>
> Has anyone else found these issues before?
>
> Thanks in advance!
>
> Aleix
>
>


Re: a small example of a REPL server

2018-11-28 Thread Christopher Lam
I saw a cute oneliner recently that I didn't note down, the gist of it 
was as follows


(let loop ((lp (interaction-environment)))
  (display (eval (read) lp))
  (newline)
  (loop lp))

Note the second line is very nearly read-eval-print-loop ;-)

On 28/11/18 6:53 pm, Catonano wrote:

Could anyone write a small example of a REPL server for me ?

The manual indicates some functions but then the code for the REPL is
overwhelming

A really small example, like the one for reading strings from the current
input port that I offered in another thread, would help

 From that, I could start for learning how to make it concurrent and maybe
let it talk a different protocol

Thanks