Re: map-par slower than map
ok , i think the problem comes both from my code and from guile parmap so. Obviously parmap could be slower on other codes because of the nature of list i think, it is hard to split a list in sublist and send them to thread and after redo a single list, i better use vector. As mentioned and forget by me, i apologize, i use an hash table which is a global variable and mutex can be set on it , no dead lock , here but it slow down the code than it is dead for speed , but not locked. The examples given are good but i do not want to write long and specific code for //, for // must a ssimple as OpenMP directives (on arrays) not be a pain in the ass like things i already did at work with GPUs in C or Fortran,that's nightmare and i do not want to have this in functional programming. ok i will try to modify the code but i do not think there is easy solution to replace the hash table, any structure i would use would be global and the problem (this function is not pure, it does a side-effect),at the end i do not think this code could be // but i'm not a specialist of //. I think this is a parallelization problem, how can we deal with a global variable such as an hash table? On Wed, Oct 12, 2022 at 11:55 PM Olivier Dion wrote: > On Wed, 12 Oct 2022, Damien Mattei wrote: > > Hello, > > all is in the title, i test on a approximately 3 element list , i got > > 9s with map and 3min 30s with par-map on exactly the same piece of > > code!? > > I can only speculate here. But trying with a very simple example here: > --8<---cut here---start->8--- > (use-modules (statprof)) > (statprof (lambda () (par-map 1+ (iota 30 > --8<---cut here---end--->8--- > > Performance are terrible. I don't know how par-map is implemented, but > if it does 1 element static scheduling -- which it probably does because > you pass a linked list and not a vector -- then yeah you can assure that > thing will be very slow. > > You're probably better off with dynamic scheduling with vectors. Here's > a quick snippet I made for static scheduling but with vectors. Feel > free to roll your own. > > --8<---cut here---start->8--- > (use-modules > (srfi srfi-1) > (ice-9 threads)) > > (define* (par-map-vector proc input > #:optional > (max-thread (current-processor-count))) > > (let* ((block-size (quotient (vector-length input) max-thread)) > (rest (remainder (vector-length input) max-thread)) > (output (make-vector (vector-length input) #f))) > (when (not (zero? block-size)) > (let ((mtx (make-mutex)) > (cnd (make-condition-variable)) > (n 0)) > (fold > (lambda (scale output) >(begin-thread > (let lp ((i 0)) > (when (< i block-size) > (let ((i (+ i (* scale block-size > (vector-set! output i (proc (vector-ref input i > (lp (1+ i > (with-mutex mtx > (set! n (1+ n)) > (signal-condition-variable cnd))) >output) > output > (iota max-thread)) > (with-mutex mtx > (while (not (< n max-thread)) > (wait-condition-variable cnd mtx > (let ((base (- (vector-length input) rest))) > (let lp ((i 0)) > (when (< i rest) > (let ((i (+ i base))) > (vector-set! output i (proc (vector-ref input i > (lp (1+ i) > output)) > --8<---cut here---end--->8--- > > -- > Olivier Dion > oldiob.dev >
Re: http-request bearer token syntax for Twitter v2 api
On 12-10-2022 12:30, Mortimer Cladwell wrote: Hi, Has anyone successfully submitted a bearer token to Twitter v2 api using http-request? What syntax did you use? Without success I have tried many permutations/splellings/capitalizations of: Note that Guile sometimes sends uncapitalised headers (as allowed by the relevant RFCs), but some implementations are stricter than permitted by the standard and expect capitalisation. See '[PATCH] web: send capitalized authorization scheme': * https://lists.gnu.org/archive/html/guile-devel/2022-06/msg00020.html * https://lists.gnu.org/archive/html/guile-devel/2022-06/msg8.html Perhaps the same thing is happening here. It appears that the patch was applied, but I don't know if it's in a release yet. Greetings, Maxime. OpenPGP_0x49E3EE22191725EE.asc Description: OpenPGP public key OpenPGP_signature Description: OpenPGP digital signature
Re: map-par slower than map
ok 'parallelization code and hash table' in google show no real solution, i have another idea,instead of function-unify-two-minterms-and-tag ,just unify the minterms and tag them (which use hash table) later out of the // region, after if it still sucks i will drop list for vectors, making it step by step will show where is the bottleneck, let me just a few time and i will go back to the mailing lists with interesting results i hope On Thu, Oct 13, 2022 at 9:40 AM Damien Mattei wrote: > ok , i think the problem comes both from my code and from guile parmap so. > Obviously parmap could be slower on other codes because of the nature of > list i think, it is hard to split a list in sublist and send them to thread > and after redo a single list, i better use vector. > As mentioned and forget by me, i apologize, i use an hash table which is a > global variable and mutex can be set on it , no dead lock , here but it > slow down the code than it is dead for speed , but not locked. > > The examples given are good but i do not want to write long and specific > code for //, for // must a ssimple as OpenMP directives (on arrays) not be > a pain in the ass like things i already did at work with GPUs in C or > Fortran,that's nightmare and i do not want to have this in functional > programming. > > ok i will try to modify the code but i do not think there is easy solution > to replace the hash table, any structure i would use would be global and > the problem (this function is not pure, it does a side-effect),at the end i > do not think this code could be // but i'm not a specialist of //. I think > this is a parallelization problem, how can we deal with a global variable > such as an hash table? > > On Wed, Oct 12, 2022 at 11:55 PM Olivier Dion > wrote: > >> On Wed, 12 Oct 2022, Damien Mattei wrote: >> > Hello, >> > all is in the title, i test on a approximately 3 element list , i >> got >> > 9s with map and 3min 30s with par-map on exactly the same piece of >> > code!? >> >> I can only speculate here. But trying with a very simple example here: >> --8<---cut here---start->8--- >> (use-modules (statprof)) >> (statprof (lambda () (par-map 1+ (iota 30 >> --8<---cut here---end--->8--- >> >> Performance are terrible. I don't know how par-map is implemented, but >> if it does 1 element static scheduling -- which it probably does because >> you pass a linked list and not a vector -- then yeah you can assure that >> thing will be very slow. >> >> You're probably better off with dynamic scheduling with vectors. Here's >> a quick snippet I made for static scheduling but with vectors. Feel >> free to roll your own. >> >> --8<---cut here---start->8--- >> (use-modules >> (srfi srfi-1) >> (ice-9 threads)) >> >> (define* (par-map-vector proc input >> #:optional >> (max-thread (current-processor-count))) >> >> (let* ((block-size (quotient (vector-length input) max-thread)) >> (rest (remainder (vector-length input) max-thread)) >> (output (make-vector (vector-length input) #f))) >> (when (not (zero? block-size)) >> (let ((mtx (make-mutex)) >> (cnd (make-condition-variable)) >> (n 0)) >> (fold >> (lambda (scale output) >>(begin-thread >> (let lp ((i 0)) >> (when (< i block-size) >> (let ((i (+ i (* scale block-size >> (vector-set! output i (proc (vector-ref input i >> (lp (1+ i >> (with-mutex mtx >> (set! n (1+ n)) >> (signal-condition-variable cnd))) >>output) >> output >> (iota max-thread)) >> (with-mutex mtx >> (while (not (< n max-thread)) >> (wait-condition-variable cnd mtx >> (let ((base (- (vector-length input) rest))) >> (let lp ((i 0)) >> (when (< i rest) >> (let ((i (+ i base))) >> (vector-set! output i (proc (vector-ref input i >> (lp (1+ i) >> output)) >> --8<---cut here---end--->8--- >> >> -- >> Olivier Dion >> oldiob.dev >> >
Re: map-par slower than map
On Thu, 13 Oct 2022, Damien Mattei wrote: > ok , i think the problem comes both from my code and from guile parmap so. > Obviously parmap could be slower on other codes because of the nature of > list i think, it is hard to split a list in sublist and send them to thread > and after redo a single list, i better use vector. > As mentioned and forget by me, i apologize, i use an hash table which is a > global variable and mutex can be set on it , no dead lock , here but it > slow down the code than it is dead for speed , but not locked. Your code is not the issue. The fact that `(par-map 1+ (iota 1000))` is slow is the proof of that. I think that you should use par-map when you want to do I/O/subprocesses in parallel. Fast computation on a huge number of items should be done with vector because of its random access nature. List are simply no the good data structure for parallelization. > The examples given are good but i do not want to write long and specific > code for //, for // must a ssimple as OpenMP directives (on arrays) not be > a pain in the ass like things i already did at work with GPUs in C or > Fortran,that's nightmare and i do not want to have this in functional > programming. You're free to use my example of `par-map-vector` and tweak it to your needs. But maybe it's time for a `guile-parallel` for fast high level parallel. If others are interested in that, I can make one. -- Olivier Dion oldiob.dev
Re: map-par slower than map
On Thu, 13 Oct 2022, Damien Mattei wrote: > i trying to use your code but it seems there is a ) mismatch > somewhere? Right there's a missing ')' a the end to close the procedure, sorry about that. -- Olivier Dion oldiob.dev
Re: map-par slower than map
i trying to use your code but it seems there is a ) mismatch somewhere? On Wed, Oct 12, 2022 at 11:55 PM Olivier Dion wrote: > On Wed, 12 Oct 2022, Damien Mattei wrote: > > Hello, > > all is in the title, i test on a approximately 3 element list , i got > > 9s with map and 3min 30s with par-map on exactly the same piece of > > code!? > > I can only speculate here. But trying with a very simple example here: > --8<---cut here---start->8--- > (use-modules (statprof)) > (statprof (lambda () (par-map 1+ (iota 30 > --8<---cut here---end--->8--- > > Performance are terrible. I don't know how par-map is implemented, but > if it does 1 element static scheduling -- which it probably does because > you pass a linked list and not a vector -- then yeah you can assure that > thing will be very slow. > > You're probably better off with dynamic scheduling with vectors. Here's > a quick snippet I made for static scheduling but with vectors. Feel > free to roll your own. > > --8<---cut here---start->8--- > (use-modules > (srfi srfi-1) > (ice-9 threads)) > > (define* (par-map-vector proc input > #:optional > (max-thread (current-processor-count))) > > (let* ((block-size (quotient (vector-length input) max-thread)) > (rest (remainder (vector-length input) max-thread)) > (output (make-vector (vector-length input) #f))) > (when (not (zero? block-size)) > (let ((mtx (make-mutex)) > (cnd (make-condition-variable)) > (n 0)) > (fold > (lambda (scale output) >(begin-thread > (let lp ((i 0)) > (when (< i block-size) > (let ((i (+ i (* scale block-size > (vector-set! output i (proc (vector-ref input i > (lp (1+ i > (with-mutex mtx > (set! n (1+ n)) > (signal-condition-variable cnd))) >output) > output > (iota max-thread)) > (with-mutex mtx > (while (not (< n max-thread)) > (wait-condition-variable cnd mtx > (let ((base (- (vector-length input) rest))) > (let lp ((i 0)) > (when (< i rest) > (let ((i (+ i base))) > (vector-set! output i (proc (vector-ref input i > (lp (1+ i) > output)) > --8<---cut here---end--->8--- > > -- > Olivier Dion > oldiob.dev >
Re: http-request bearer token syntax for Twitter v2 api
Hi Mortimer, > Has anyone successfully submitted a bearer token to Twitter v2 api using > http-request? What syntax did you use? The validator for the Authorization header does not permit the “bearer” method with a single string. It expects that authentication methods other than Basic always provide key=value arguments. So we have to overwrite things: --8<---cut here---start->8--- (import (ice-9 pretty-print) (ice-9 match) (json) (rnrs bytevectors) (web client) (web http) (web request) (web response)) (define* (parse-credentials str #:optional (val-parser (@@ (web http) default-val-parser)) (start 0) (end (string-length str))) (let* ((start ((@@ (web http) skip-whitespace) str start end)) (delim (or (string-index str char-set:whitespace start end) end))) (when (= start end) ((@@ (web http) bad-header-component) 'authorization str)) (let ((scheme (string->symbol (string-downcase (substring str start (or delim end)) (case scheme ((bearer) (let* ((start ((@@ (web http) skip-whitespace) str delim end))) (unless (< start end) (pk 'oh start end str) ((@@ (web http) bad-header-component) 'token str)) (cons scheme (substring str start end (else ((@@ (web http) parse-credentials) str val-parser start end)) (define (validate-credentials val) (match val (((or 'basic 'bearer) . (? string?)) #t) (((? symbol?) . (? (@@ (web http) key-value-list?))) #t) (_ #f))) (define put-string (@@ (web http) put-string)) (define (write-credentials val port) (match val (('bearer . cred) (put-string port "bearer ") (put-string port cred)) (_ ((@@ (web http) write-credentials) val port (declare-header! "authorization" parse-credentials validate-credentials write-credentials) (let* ((uri "https://api.twitter.com/2/users/2244994945/tweets?tweet.fields=created_at&expansions=author_id&user.fields=created_at&max_results=5";) (my-token "AAA...") (my-headers `((Content-type . "application/json") (authorization . (bearer . ,my-token) (call-with-values (lambda () (http-get uri #:headers my-headers)) (lambda (response body) (pretty-print response) (pretty-print (json-string->scm (utf8->string body)) --8<---cut here---end--->8--- Note that the POST endpoint for submitting tweets does not allow bearer token authentication. -- Ricardo
Fwd: map-par slower than map
sorry google always do reply to single author... -- Forwarded message - From: Damien Mattei Date: Thu, Oct 13, 2022 at 1:56 PM Subject: Re: map-par slower than map To: Olivier Dion ah just at the end? i had noticed, but i get #unspecifeid ? so my new code is not good if your procedure is, i will check it,thanks. Damien On Thu, Oct 13, 2022 at 1:00 PM Olivier Dion wrote: > On Thu, 13 Oct 2022, Damien Mattei wrote: > > i trying to use your code but it seems there is a ) mismatch > > somewhere? > > Right there's a missing ')' a the end to close the procedure, sorry > about that. > > -- > Olivier Dion > oldiob.dev >
Re: map-par slower than map
the code did not worked when data length were more little than number of cpus (6 on my host) (iota 5) returns #unsepcified: scheme@(guile-user)> (use-modules (ice-9 threads)) scheme@(guile-user)> {v <+ (list->vector (iota 5))} #(0 1 2 3 4) scheme@(guile-user)> (par-map-vector sqrt v) scheme@(guile-user)> {v <+ (list->vector (iota 20))} #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19) scheme@(guile-user)> (par-map-vector sqrt v) #(0 1 1.4142135623730951 1.7320508075688772 2 2.23606797749979 2.449489742783178 2.6457513110645907 2.8284271247461903 3 3.1622776601683795 3.3166247903554 3.4641016151377544 3.605551275463989 3.7416573867739413 3.872983346207417 4 4.123105625617661 4.242640687119285 4.358898943540674) scheme@(guile-user)> (current-processor-count) 6 scheme@(guile-user)> {v <+ (list->vector (iota 6))} #(0 1 2 3 4 5) scheme@(guile-user)> (par-map-vector sqrt v) #(0 1 1.4142135623730951 1.7320508075688772 2 2.23606797749979) so i modify it this way: (define* (par-map-vector proc input #:optional (max-thread (current-processor-count))) (if (< (vector-length input) max-thread) (list->vector (map proc (vector->list input))) ;; less data than threads or CPUs (let* ((block-size (quotient (vector-length input) max-thread)) (rest (remainder (vector-length input) max-thread)) (output (make-vector (vector-length input) #f))) (when (not (zero? block-size)) (let ((mtx (make-mutex)) (cnd (make-condition-variable)) (n 0)) (fold (lambda (scale output) (begin-thread (let lp ((i 0)) (when (< i block-size) (let ((i (+ i (* scale block-size (vector-set! output i (proc (vector-ref input i (lp (1+ i (with-mutex mtx (set! n (1+ n)) (signal-condition-variable cnd))) output) output (iota max-thread)) (with-mutex mtx (while (not (< n max-thread)) (wait-condition-variable cnd mtx (let ((base (- (vector-length input) rest))) (let lp ((i 0)) (when (< i rest) (let ((i (+ i base))) (vector-set! output i (proc (vector-ref input i (lp (1+ i) output now it works but crash randomly, not even at the same stage, i continue to test and debug On Thu, Oct 13, 2022 at 1:57 PM Damien Mattei wrote: > sorry google always do reply to single author... > > -- Forwarded message - > From: Damien Mattei > Date: Thu, Oct 13, 2022 at 1:56 PM > Subject: Re: map-par slower than map > To: Olivier Dion > > > ah just at the end? i had noticed, but i get #unspecifeid ? so my new code > is not good if your procedure is, i will check it,thanks. > Damien > > On Thu, Oct 13, 2022 at 1:00 PM Olivier Dion > wrote: > >> On Thu, 13 Oct 2022, Damien Mattei wrote: >> > i trying to use your code but it seems there is a ) mismatch >> > somewhere? >> >> Right there's a missing ')' a the end to close the procedure, sorry >> about that. >> >> -- >> Olivier Dion >> oldiob.dev >> >
Re: map-par slower than map
On Thu, 13 Oct 2022, Damien Mattei wrote: > the code did not worked when data length were more little than number of > cpus (6 on my host) (iota 5) returns #unsepcified: Yeah sorry I miss indended the output and the rest. Here's a version that should work: --8<---cut here---start->8--- (use-modules (srfi srfi-1) (ice-9 threads)) (define* (par-map-vector proc input #:optional (max-thread (current-processor-count))) (let* ((block-size (quotient (vector-length input) max-thread)) (rest (remainder (vector-length input) max-thread)) (output (make-vector (vector-length input) #f))) (when (not (zero? block-size)) (let ((mtx (make-mutex)) (cnd (make-condition-variable)) (n 0)) (fold (lambda (scale output) (begin-thread (let lp ((i 0)) (when (< i block-size) (let ((i (+ i (* scale block-size (vector-set! output i (proc (vector-ref input i (lp (1+ i (with-mutex mtx (set! n (1+ n)) (signal-condition-variable cnd))) output) output (iota max-thread)) (with-mutex mtx (while (not (< n max-thread)) (wait-condition-variable cnd mtx) (let ((base (- (vector-length input) rest))) (let lp ((i 0)) (when (< i rest) (let ((i (+ i base))) (vector-set! output i (proc (vector-ref input i (lp (1+ i) output)) --8<---cut here---end--->8--- -- Olivier Dion oldiob.dev
Re: map-par slower than map
i do not see what has changed in your code ? really strange,even with bad code the moment it crash should be the same, sometimes works,crash or freeze On Thu, Oct 13, 2022 at 2:41 PM Olivier Dion wrote: > On Thu, 13 Oct 2022, Damien Mattei wrote: > > the code did not worked when data length were more little than number of > > cpus (6 on my host) (iota 5) returns #unsepcified: > > Yeah sorry I miss indended the output and the rest. Here's a version > that should work: > --8<---cut here---start->8--- > (use-modules > (srfi srfi-1) > (ice-9 threads)) > > (define* (par-map-vector proc input > #:optional > (max-thread (current-processor-count))) > > (let* ((block-size (quotient (vector-length input) max-thread)) > (rest (remainder (vector-length input) max-thread)) > (output (make-vector (vector-length input) #f))) > (when (not (zero? block-size)) > (let ((mtx (make-mutex)) > (cnd (make-condition-variable)) > (n 0)) > (fold > (lambda (scale output) >(begin-thread > (let lp ((i 0)) > (when (< i block-size) > (let ((i (+ i (* scale block-size > (vector-set! output i (proc (vector-ref input i > (lp (1+ i > (with-mutex mtx > (set! n (1+ n)) > (signal-condition-variable cnd))) >output) > output > (iota max-thread)) > (with-mutex mtx > (while (not (< n max-thread)) > (wait-condition-variable cnd mtx) > (let ((base (- (vector-length input) rest))) > (let lp ((i 0)) > (when (< i rest) > (let ((i (+ i base))) > (vector-set! output i (proc (vector-ref input i > (lp (1+ i) > output)) > --8<---cut here---end--->8--- > > -- > Olivier Dion > oldiob.dev >
Re: map-par slower than map
On Thu, 13 Oct 2022, Damien Mattei wrote: > i do not see what has changed in your code ? Just copy it. Trust me it has changed. > really strange,even with bad code the moment it crash should be the same, > sometimes works,crash or freeze I don't get any of these problem .. running with (iota 1) I don't see any synchornization issue also. -- Olivier Dion oldiob.dev
Re: map-par slower than map
On Thu, Oct 13, 2022 at 4:06 PM Olivier Dion wrote: > On Thu, 13 Oct 2022, Damien Mattei wrote: > > i do not see what has changed in your code ? > > Just copy it. Trust me it has changed. > really ? :-) i read it 3 times line by line, yes the end is cut ,still no ending ) and i use it and freeze,crash or ok randomly, the first times it works but try 4 or 5 examples :-( > > > really strange,even with bad code the moment it crash should be the same, > > sometimes works,crash or freeze > > I don't get any of these problem .. running with (iota 1) I > don't see any synchornization issue also. > > -- > Olivier Dion > oldiob.dev >
Re: map-par slower than map
ok i have the proof, this time (second time) the process stopped itself on your example ("processus stoppé " in french) : mattei@pc-mattei:~/Dropbox/git/library-FunctProg$ guile GNU Guile 3.0.1 Copyright (C) 1995-2020 Free Software Foundation, Inc. Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'. This program is free software, and you are welcome to redistribute it under certain conditions; type `,show c' for details. Enter `,help' for help. scheme@(guile-user)> (use-modules (srfi srfi-1) (ice-9 threads)) scheme@(guile-user)> (define* (par-map-vector proc input #:optional (max-thread (current-processor-count))) (if (< (vector-length input) max-thread) (list->vector (map proc (vector->list input))) ;; less data than threads or CPUs (let* ((block-size (quotient (vector-length input) max-thread)) (rest (remainder (vector-length input) max-thread)) (output (make-vector (vector-length input) #f))) (when (not (zero? block-size)) (let ((mtx (make-mutex)) (cnd (make-condition-variable)) (n 0)) (fold (lambda (scale output) (begin-thread (let lp ((i 0)) (when (< i block-size) (let ((i (+ i (* scale block-size (vector-set! output i (proc (vector-ref input i (lp (1+ i (with-mutex mtx (set! n (1+ n)) (signal-condition-variable cnd))) output) output (iota max-thread)) (with-mutex mtx (while (not (< n max-thread)) (wait-condition-variable cnd mtx ;; (let ((base (- (vector-length input) rest))) ;; (let lp ((i 0)) ;; (when (< i rest) ;;(let ((i (+ i base))) ;; (vector-set! output i (proc (vector-ref input i ;;(lp (1+ i) output scheme@(guile-user)> (define v (list->vector (iota 1) )) scheme@(guile-user)> (define r (par-map-vector sqrt v)) scheme@(guile-user)> (define v (list->vector (iota 1) )) scheme@(guile-user)> (define r (par-map-vector sqrt v)) Processus arrêté the first time is ok but the second time, Guile quit to the terminal. seems something makes the guile system instable after one run, i test it out of my program and out of my Scheme+ but my .guile is in this directory like that: ; Guile config file ;; history (use-modules (ice-9 readline) (ice-9 history) (srfi srfi-43) ;; vector ;; guile object oriented programming system (oop goops) (oop goops describe)) (activate-readline) ;;(disable-value-history!) ;; curly infix as in srfi-105 (read-enable 'curly-infix) ;; set current path in load path (set! %load-path (reverse (cons "." (reverse %load-path ;; other solution is to put this in shell: ;; export GUILE_LOAD_PATH="...:." On Thu, Oct 13, 2022 at 4:10 PM Damien Mattei wrote: > > > On Thu, Oct 13, 2022 at 4:06 PM Olivier Dion > wrote: > >> On Thu, 13 Oct 2022, Damien Mattei wrote: >> > i do not see what has changed in your code ? >> >> Just copy it. Trust me it has changed. >> > really ? :-) i read it 3 times line by line, yes the end is cut ,still no > ending ) and i use it and freeze,crash or ok randomly, the first times it > works but try 4 or 5 examples :-( > >> >> > really strange,even with bad code the moment it crash should be the >> same, >> > sometimes works,crash or freeze >> >> I don't get any of these problem .. running with (iota 1) I >> don't see any synchornization issue also. >> >> -- >> Olivier Dion >> oldiob.dev >> >
Re: http-request bearer token syntax for Twitter v2 api
Thanks Ricardo. I used your over-writes and modified my code below: (let* ( (uri "https://api.twitter.com/2/tweets";) (data "{\"text\":\"Hello world!\"}") (access-token "abcdemyaccesstoken") (my-headers `((Content-type . "application/json")(authorization . (bearer . ,access-token)) )) ) (call-with-values (lambda () (http-request uri #:method 'POST #:body data #:headers my-headers)) (lambda (response body) (pretty-print response) (pretty-print (json-string->scm (utf8->string body) ) the error body: (("type" . "https://api.twitter.com/2/problems/invalid-request";) ("detail" . "One or more parameters to your request was invalid.") ("title" . "Invalid Request") ("errors" . #((("message" . "Requests with bodies must have content-type of application/json.") >>Note that the POST endpoint for submitting tweets does not allow bearer token authentication. I am using Oauth2 with PKCE. I submit an authorization token to obtain and access-token and refresh token. I can then successfully tweet with the guile/curl code: (let* ((access-token "abcdemyaccesstoken") (a "--header") (b "Content-type: application/json") (c (string-append "Authorization: Bearer " access-token)) (d "{\"text\":\"Yay! I’m Tweeting from the API!\"}") ) (system* "curl" "--cacert" "./ca/cacert.pem" "-X" "POST" " https://api.twitter.com/2/tweets"; a b a c "-d" d) )) Note I am using an access token with "...Bearer...". A twitter bug? or I am confused by the terminology. In any case works with curl but not guile http-request. Thanks Mortimer