Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

a list of a single char is returned with double quotes #15

Open
jhwu68 opened this issue Oct 29, 2024 · 8 comments
Open

a list of a single char is returned with double quotes #15

jhwu68 opened this issue Oct 29, 2024 · 8 comments

Comments

@jhwu68
Copy link

jhwu68 commented Oct 29, 2024

@guregu Hi, we're running into this weird behavior, it's probably a trealla thing, since it doesn't happen with swi-prolog. Is there a quick fix or workaround?

Screenshot 2024-10-29 at 17 13 11
@jhwu68 jhwu68 changed the title a list of a single char is displayed with double quotes a list of a single char is returned with double quotes Oct 30, 2024
@guregu
Copy link
Collaborator

guregu commented Oct 30, 2024

Hello @jhwu68, depends on where you're running into this.
By default [a] and "a" are just two ways of writing the same thing, so it's (supposed to be) harmless.

?- "a" = [a].
   true.
?- "ab" = [a, b].
   true.

You can disable this in the terminal output with set_prolog_flag(answer_write_options, [double_quotes(false)]).

?- set_prolog_flag(answer_write_options, [double_quotes(false)]).
   true.
?- findall(Col, member(Col, [a]), List).                                                                                                                                                
   List = [a].

If you want to run this automatically when you load a script you can add this to the file:

:- initialization(set_prolog_flag(answer_write_options, [double_quotes(false)])).

and it should apply globally.

But, if you're running into an issue, say with Scan or some other encoding/decoding thing, maybe there's another issue. Let me know and I'll help out.

BTW the reason SWI gives you a different result is that by default SWI treats double-quoted strings as lists of character codes instead of lists of single characters. You can configure Trealla to do this too but it breaks a lot of stuff. In general the character way (Trealla default) is "better".

@jhwu68
Copy link
Author

jhwu68 commented Oct 30, 2024

@guregu thanks for the explanation. I kind of understand they represent the same thing. but it's not parsed into slice in go, where we check the type of the value.

i tried wth adding initialization, but still the same result
Screenshot 2024-10-30 at 18 04 39

and the specific issue we have is
Screenshot 2024-10-30 at 17 55 07

i made a workaround in go https://github.com/aukai/stream.api/pull/1296

@guregu
Copy link
Collaborator

guregu commented Oct 30, 2024

@jhwu68 They removed me from that repo recently ;(
Are you using .Scan? I think I found the issue, maybe! Pushing now

@guregu
Copy link
Collaborator

guregu commented Oct 30, 2024

Oh, I can probably guess what it is assuming that code hasn't changed much. I see... sorry about that.
My fix kinda helps but not for your case (yet).
I imagine your workaround is something like

var cols []trealla.Term
switch x := cmp.Args[4].(type) {
case []trealla.Term:
	cols = x
case string:
	for char := range x {
		cols = append(cols, String(char))
	}
}

which should be fine but it's not too pretty to look at.
I'll add a nicer way to do this so you can just write trealla.Convert(cmp.Args[4], &cols) or something.

@guregu
Copy link
Collaborator

guregu commented Oct 30, 2024

For this use case it might be nicest to disable strings in results in general. I should be able to add a query option that does that. I’ll get back to you.

@jhwu68
Copy link
Author

jhwu68 commented Oct 30, 2024

They removed me from that repo recently ;(

😢
yeah, the workaround is similar to that. Thanks for looking into it!

@guregu
Copy link
Collaborator

guregu commented Nov 2, 2024

@jhwu68 I improved the Scan function in the latest release, so you can unmarshal query results into structs:

type pair struct {
	trealla.Functor `prolog:"-/2"`
	Key     trealla.Term
	Value   trealla.Term
}
type fieldDef struct {
	trealla.Functor `prolog:"field/5"`
	Path    Atom
	Type    trealla.Term
	Options []trealla.Term
	Rules   []pair
	Cols    []trealla.Atom
}
var result struct {
	Fields []fieldDef
}
answer, err := pl.QueryOnce(`findall(..., Fields).`)
answer.Solution.Scan(&result)

It will be smart enough to handle turning strings into slices, and less .(type) shenanigans too. I added some test cases with the string -> slice thing so hopefully you won't run into the same problem again.

@jhwu68
Copy link
Author

jhwu68 commented Nov 12, 2024

@guregu thanks! will check out the latest release soon, and close the issue if looks good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants