Lisp Scheme using (string-set!) Error Encountered - string

I am new to (Lisp) scheme programming and have been following the tutorial. Everything went well until I use string-set!
String-set! is use to replace the character at index. An example of what I did below:
Welcome to Racket v5.1.3.
> (define greeting "Hello; Hello!")
> (string-set! greeting 1 #\a)
string-set!: expects type <mutable string> as 1st argument, given: "Hello; Hello!"; other arguments were: 1 #\a
=== context ===
/usr/share/racket/collects/racket/private/misc.rkt:85:7
> greeting
"Hello; Hello!"
>
When (string-set! greeting 1 #\a) executed, it should replace the first 'e' to 'a' according to the tutorial. The output should be:
> greeting
"Hallo; Hello!"
But instead I am getting the error string-set!: expects type <mutable string> as 1st argument.
Am I doing it the wrong way?

As per the Racket documentation:
A string can be mutable or immutable. When an immutable string is provided to a procedure like string-set!, the exn:fail:contract exception is raised. String constants generated by the default reader (see Reading Strings) are immutable, and they are interned in read-syntax mode.
You can use string-copy to make a copy of a string, and this always returns a mutable string.
(define greeting (string-copy "Hello; Hello!"))

Your code is not suppose to work according to the R5RS or R6RS. It clearly states:
(define (g) "***")
(string-set! (g) 0 #\?) ===> error
It might be an error in your tutorial. You need to make the string mutable:
(define greeting (string-copy "Hello; Hello!"))
(string-set! greeting 1 #\a)
greeting ; ==> "Hallo; Hello!"
BTW: When you start Racket from command line or DrRacket in a windowed environment your are not expected to write Scheme, but a dialect that has diverged from the standard called racket. Most of Scheme will work though, but not set-car! or set-cdr!.
I advice you to use a Scheme standard according your tutorial. To use racket to run a Scheme standard from command line, you start either plt-r5rs or plt-r6rs. In DrRacket you can use choose language in the bottom left. Choose "Other > Legacy language R5RS" or select The racket language and start your definitions windows with:
#!r6rs
(import (rnrs))
DrRacket has a debugger so I recommend it. I googled your line and if you are following Teach Yourself Scheme in Fixnum Days, it conforms to the R5RS standard.
If you rather want to learn racket I recommend Realm of racket (2013) since you make games, which are fun. There is also a free book called How to design programs (2003).

Related

What $() syntax means for Groovy language?

I found this in Groovy Syntax documentation at 4.6.1. Special cases:
As slashy strings were mostly designed to make regexp easier so a few
things that are errors in GStrings like $() or $5 will work with
slashy strings.
What $() syntax means? give some usage examples please
I also found it at Define the Contract Locally in the Repository of the Fraud Detection Service:
body([ // (4)
"client.id": $(regex('[0-9]{10}')),
loanAmount : 99999
])
but I don't understand what $() means when used with regex('[0-9]{10}').
It means nothing (or what you make of it). There are two places, you
are addressing, but they have nothing to do with each other.
The docs just mention this as "you can use slashy strings to write
things, that would give you an error with a GString" - the same is true
for just using '-Strings.
E.g.
"hello $()"
Gives this error:
unknown recognition error type: groovyjarjarantlr4.v4.runtime.LexerNoViableAltException
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/tmp/x.groovy: 1: token recognition error at: '(' # line 1, column 9.
"hello $()"
The parser either wants a { or any char, that is a valid first char
for a variable (neither ( nor 5 is).
The other place you encountered $() (in Spring cloud contract), this
is just a function with the name $.
Form the docs 8. Contract DSL:
You can set the properties inside the body either with the value method or, if you use the Groovy map notation, with $()
So this is just a function, with a very short name.
E.g. you can try this yourself:
void $(x) { println x }
$("Hello")

Sublime Text 3 custom syntax for cottle: hard to start

I'm trying to make a "very simple" syntax highlight for "cottle" (which is a script language used in a text-to-speech app dedicated to Elite:Dangerous).
All i want (at least at the beginning) is to have three different colours: Comments, "non-strings", and strings.
I started trying with the ST3 wiki, youtube tutorials, questions here.... but i can't sort out how to do it, 'cause the way the language work.
I'll try to show you an example
{ everything_between_a_pair_of_brackets_is_code }
everything outside all pairs of bracket is a string {_ and this is a comment. It begins with "_" and ends at the closing bracket }
{ This_is_code("but this is a string")
This_is_still_code("this is also a string {but_this_is_code(\"and a string\")} and this the end of the string")
}
My problem is how to define this kind of "nidification" in my cottle.sublime-syntax file. I managed to get the comment, but only the first one.
- EDIT -
This is a real script:
{event.item}
{if event.repairedfully:
fully repaired
|else:
partially repaired
{Occasionally(2,
cat(
OneOf("to ", "at "),
Humanise(event.health * 100),
" percent functionality"
)
)}
}
{Occasionally(2,
cat(OneOf(", ", "and is"), " ready for re-activation")
)}.
The output of this script could be "Engine module fully repaired." or "Engine module partially repaired, and is ready for re-activation."
Please note the last dot of the phrase, which in the code is after the last bracket.
This is another sample, with strings passed to functions inside other strings:
{OneOf("{ShipName()} has", "")}
{OneOf("left supercruise", "{OneOf(\"entered\", \"returned to\", \"dropped to\")} normal space")}
My question is:
how sublime-syntax files handle this kind of nidification?
Looking at the overview of the templating language over at https://cottle.readthedocs.io/en/stable/page/01-overview.html, it seems to be an easy syntax for which to write a .sublime-syntax for, but given the utter lack of resources for knowing how syntax files works in ST, I can understand it can be sometimes difficult to start or even understand.
So, I took the liberty of creating a starter syntax definition (the result of an hour & a half of boredom on a Saturday evening), which you can take and work upon. Note that I have not used the language and as such made it by just reading the docs and looking over code snippets.
You can find a gist for it here (https://gist.github.com/Ultra-Instinct-05/96fa99e1aaeb32b12d1e62109d61fcc2)
Here is a screenshot showing it in the color scheme I use (which follows the official scope naming guidelines).
It still lacks support for user defined functions (as I came to know from the docs) (and probably a few other things), but maybe that's something you can add to it !
Note that to use it, save the file as Cottle.sublime-syntax in your User package. Right now files having a .cottle extension are highlighted (because I don't know how you create a cottle file).
The syntax definition doesn't use any new feature added in ST4, so it should work the same in both ST3 & ST4.

F# interactive commands corresponds to ghci :t :i

I'm learning F# via F# interactive.
Is there commands that acts like GHCi :t, :i?
:t value shows the type of value.
:i type shows the top-level declarations of type.
Reference: fsharp-interactive
In F# Interactive you can just write the name of function to see its type. If, for example, you want to see the types of id, string, or List.map, just write them:
> id;;
val it : ('a -> 'a)
> string;;
val it : (obj -> string) = <fun:it#6-3>
> List.map;;
val it : (('a -> 'b) -> 'a list -> 'b list)
That gives you functionality similar to :t in GHCi.
I'm not aware of any command that corresponds to :i, although I admit that it would be useful.
I recommend that you never type directly into FSI. Use an editor with F# support like Visual Studio, VS Code or Rider. Write code in the editor, select definitions or expressions in the code and send to FSI (usually with Alt-Enter). This will provide a much better experience and save you lots of time. The benefits:
Type information on hover for any symbols (including the type parameters of a function and what they might be constrained to in a particular context)
Live type-error checking over multiple functions/values
Auto-complete suggestions
Syntax highlighting
No need to put ;; at the end of any lines
I've been writing F# for several years with heavy use of FSI and after the first day I have never ever typed into FSI because there is no advantage in doing so.

Is it possible / easy to include some mruby in a nim application?

I'm currently trying to learn Nim (it's going slowly - can't devote much time to it). On the other hand, in the interests of getting some working code, I'd like to prototype out sections of a Nim app I'm working on in ruby.
Since mruby allows embedding a ruby subset in a C app, and since nim allows compiling arbitrary C code into functions, it feels like this should be relatively straightforward. Has anybody done this?
I'm particularly looking for ways of using Nim's funky macro features to break out into inline ruby code. I'm going to try myself, but I figure someone is bound to have tried it and /or come up with more elegant solutions than I can in my current state of learning :)
https://github.com/micklat/NimBorg
This is a project with a somewhat similar goal. It targets python and lua at the moment, but using the same techniques to interface with Ruby shouldn't be too hard.
There are several features in Nim that help in interfacing with a foreign language in a fluent way:
1) Calling Ruby from Nim using Nim's dot operators
These are a bit like method_missing in Ruby.
You can define a type like RubyValue in Nim, which will have dot operators that will translate any expression like foo.bar or foo.bar(baz) to the appropriate Ruby method call. The arguments can be passed to a generic function like toRubyValue that can be overloaded for various Nim and C types to automatically convert them to the right Ruby type.
2) Calling Nim from Ruby
In most scripting languages, there is a way to register a foreign type, often described in a particular data structure that has to be populated once per exported type. You can use a bit of generic programming and Nim's .global. vars to automatically create and cache the required data structure for each type that was passed to Ruby through the dot operators. There will be a generic proc like getRubyTypeDesc(T: typedesc) that may rely on typeinfo, typetraits or some overloaded procs supplied by user, defining what has to be exported for the type.
Now, if you really want to rely on mruby (because you have experience with it for example), you can look into using the .emit. pragma to directly output pieces of mruby code. You can then ask the Nim compiler to generate only source code, which you will compile in a second step or you can just change the compiler executable, which Nim will call when compiling the project (this is explained in the same section linked above).
Here's what I've discovered so far.
Fetching the return value from an mruby execution is not as easy as I thought. That said, after much trial and error, this is the simplest way I've found to get some mruby code to execute:
const mrb_cc_flags = "-v -I/mruby_1.2.0_path/include/ -L/mruby_1.2.0_path/build/host/lib/"
const mrb_linker_flags = "-v"
const mrb_obj = "/mruby_1.2.0_path/build/host/lib/libmruby.a"
{. passC: mrb_cc_flags, passL: mrb_linker_flags, link: mrb_obj .}
{.emit: """
#include <mruby.h>
#include <mruby/string.h>
""".}
proc ruby_raw(str:cstring):cstring =
{.emit: """
mrb_state *mrb = mrb_open();
if (!mrb) { printf("ERROR: couldn't init mruby\n"); exit(0); }
mrb_load_string(mrb, `str`);
`result` = mrb_str_to_cstr(mrb, mrb_funcall(mrb, mrb_top_self(mrb), "test_func", 0));
mrb_close(mrb);
""".}
proc ruby*(str:string):string =
echo ruby_raw("def test_func\n" & str & "\nend")
"done"
let resp = ruby """
puts 'this was a puts from within ruby'
"this is the response"
"""
echo(resp)
I'm pretty sure that you should be able to omit some of the compiler flags at the start of the file in a well configured environment, e.g. by setting LD_LIBRARY_PATH correctly (not least because that would make the code more portable)
Some of the issues I've encountered so far:
I'm forced to use mrb_funcall because, for some reason, clang seems to think that the mrb_load_string function returns an int, despite all the c code I can find and the documentation and several people online saying otherwise:
error: initializing 'mrb_value' (aka 'struct mrb_value') with an expression of incompatible type 'int'
mrb_value mrb_out = mrb_load_string(mrb, str);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
The mruby/string.h header is needed for mrb_str_to_cstr, otherwise you get a segfault. RSTRING_PTR seems to work fine also (which at least gives a sensible error without string.h), but if you write it as a one-liner as above, it will execute the function twice.
I'm going to keep going, write some slightly more idiomatic nim, but this has done what I needed for now.

Scheme check between multiple strings

Out of practice to make myself more familiar with the scheme interface, I'm trying to write a procedure in Dr. Racket (though compatible with MIT Scheme) that checks between various different strings given and returns the appropriate strings depending on what is provided. What I have so far is this:
(define (conversation input)
(cond ((eq? (or "hello Racket" "hi Racket" "what's up, Racket?"
"hey Racket" "what's happening, Racket?") input) "hey coder")
(else "no hablo ingles.")))
*the space in between the strings is just so it will fit on here. It's one long statement in the interpreter.
The desired effect is that if I put in:
(conversation "hello Racket")
(conversation "hi Racket")
(conversation "hey Racket")
They will all return the same result, which is "hey coder". However, that is not what's happening. The only one that returns "hey coder" is (conversation "hello Racket"). All the rest return "no hable ingles." As with many other aspects of the language, I'm not all too savvy with strings in scheme. I'm fairly certain that the problem lies within the or statement, though I wouldn't know of the alternatives that would work in this context. I've tried looking up solutions, though I haven't run across anything that fits this type of description. Does anyone know of any alternatives to the code that would work?
or takes a list of arguments and checks whether any of its arguments are "truthy" (that is not #f). If so, it returns the first of its arguments that is truthy. If not, it returns #f. So (or "string1" "string2" ...) simply returns "string1". So all you're doing is checking whether the given string equals "hello Racket" and ignoring the other options (you might object here that it doesn't work for "hello Racket" either - I'll get to that). What you want to be doing is to give whole conditions to or, not just the strings. So it should look like (or (eq? "string1" input) (eq? "string2" input) ...).
However this doesn't work either. Why not? Because eq? is the wrong function to use to compare strings. It only returns true if two strings reside in the same location in memory. If two strings reside in different memory locations, but have the same contents, it returns #f. This is also why your current code returns #f for "hello Racket". What you should be using is equal?, which compares the contents of the strings.
This should work now, but it's a bit clunky - repeating the call to equal? for every possible string. A nicer approach would be to create a list with the valid strings and then check whether the input string is contained in the list using the member function.
You can achieve the effect that you intended using the member procedure and a list of possible options:
member locates the first element of lst that is equal? to v. If such an element exists, the tail of lst starting with that element is returned. Otherwise, the result is #f.
This is what I mean:
(define (conversation input)
(cond ((member input '("hello Racket" "hi Racket" "what's up, Racket?"
"hey Racket" "what's happening, Racket?"))
"hey coder")
(else "no hablo ingles.")))

Resources