Does Rust support Ruby-like string interpolation? - rust

In Ruby I could do this.
aaa = "AAA"
bbb = "BBB #{aaa}"
puts(bbb)
> "BBB AAA"
The point of this syntax is eliminating repetition, and making it to feel like a shell script - great for heavy string manipulation.
Does Rust support this? Or have plan to support this? Or have some feature which can mimic this?

Rust has string formatting.
fn main() {
let a = "AAA";
let b = format!("BBB {}", a);
println(b);
}
// output: BBB AAA
In the Rust version, there is no additional repetition but you must explicitly call format!() and the inserted values are separated from the string. This is basically the same way that Python and C# developers are used to doing things, and the rationale is that this technique makes it easier to localize code into other languages.
The Rust mailing list has an archived discussion ([rust-dev] Suggestions) in which the different types of string interpolation are discussed.

This is available since Rust 1.58! Here's the syntax:
let (person, species, name) = ("Charlie Brown", "dog", "Snoopy");
// implicit named argument `person`
print!("Hello {person}");
// implicit named arguments `species` and `name`
format!("The {species}'s name is {name}.");
RFC 2795 is the original proposal.

As of Rust 1.58, you can take advantage of captured identifiers in format strings. That lets you do stuff like this:
let msg = "here";
let s = format!("Abc {msg}");
println!("Hi t{msg}"); // prints "Hi there"
println!("{s}"); // prints "Abc here"
This feature can be seen as a subset of string interpolation. Expressions like format!("Abc {a+b}") are not supported and it's unclear whether such a feature will ever be added. There have also been discussions on adding a subset of expressions for dotted paths, as in format!("Abc {foo.bar}").
Also note that the Rust 2021 Edition makes room for future additions to the language, such as f"hello {name}", which would allow for a much more concise string interpolation, comparable to most other modern languages.

Related

Why purely functional languages allow passing parameters only by value?

I'm new to functional languages and I was wondering why we can't pass a parameter by reference.
I found anserws saying that
you are not supposed to change the state of objects once they have been created
but I didn't quite get the idea.
It's not so much that you can't pass references, it's that with referential transparency there isn't a programmer-visible difference between references and values, because you aren't allowed to change what references point to. This makes it actually safer and more prevalent in pure functional programming to pass shared references around everywhere. From a semantic point of view, they may as well be values.
I think you have misunderstood the concept. Both Scheme and C/C++ are pass by value languages and most values are addresses (references).
Purely functional languages can have references and those are passed by value. What they don't have is redefining variables in the same scope (mutate bindings) and they don't have the possibility to update the object the reference points to. All operations return a fresh new object.
As an example I can give you Java's strings. Java is not purely functional but its strings are. If you change the string to uppercase you get a new string object in return and the original one has not been altered.
Most languages I know of are pass by value. Pass by name is alien to me.
Because if you pass params by reference you could change something in the parameter, which could introduce a side effect. Consider this:
function pay(person, cost) {
person.wallet -= cost;
}
function money(person) {
return person.wallet;
}
let joe = { name: "Joe", wallet: 300 };
console.log(money(joe)); // 300
pay(joe, 20);
console.log(money(joe)); // 280
The two money(joe) are taking the same input (the object joe) and giving different output (300, 280). This is in contradiction to the definition of a pure functional language (all functions must return the same output when given the same input).
If the program was made this way, there is no problem:
function pay(person, cost) {
return Object.freeze({ ...person, wallet: person.wallet - cost });
}
function money(person) {
return person.wallet;
}
let joe = Object.freeze({ name: "Joe", wallet: 300 });
console.log(money(joe)); // 300
let joe_with_less_money = pay(joe, 20);
console.log(money(joe)); // still 300
console.log(money(joe_with_less_money)); // 280
Here we have to fake pass-by-value by freezing objects (which makes them immutable) since JavaScript can pass parameters only one way (pass by sharing), but the idea is the same.
(This presupposes the implications of the term "pass-by-reference" that apply to languages like C++, where the implementation detail affects mutability, not the actual implementation detail of modern languages, where references are typically passed under the hood but immutability is assured by other means.)

Is it possible to mutate a string in Swift such that it can be proven to modify the original value?

Start with the claim that Swift makes that strings are 'mutable', Are Swift "mutable" strings really mutable, or are they just like Java strings?, but proceeding with a generally-accepted (and non-Swift) definition of mutability - ie. strictly value immutability, without consideration of bindings
Is it possible to actually mutate a String value such that this prints 'true'?
var str = "Mutate me!"
let a1 = (unsafeAddressOf(str))
// some 'mutating operation'
let a2 = (unsafeAddressOf(str))
print(a1 == a2)
I am not interested in 'structure types' or delayed copy semantics. This question is about if a string value can be modified, from within Swift - although it would be also be interesting to see if such could be mutated by other .. devious means. (If not it is hogwash to even bother discussing value vs reference types instead of pure mutability considerations.)
I am aware of "mutating" methods but disagree with those as 'mutating' the string value. In the example above, let should be substitutable in the final program. If let cannot be substituted; or the object can otherwise not be proven to be the same, then mutability has not been shown.

Static languages that can manipulate object properties?

Something that comes up a fair amount when dealing with heterogeneous data is the need to partially change simple objects that hold data. For instance, you might want to add, drop, or rename a property, or concatenate two objects. This is easy enough in dynamic languages, but I'm wondering if there are any clever solutions proposed by static languages?
To fix ideas, are there any languages that enable, perhaps through some sort of static mixin syntax, something like this (C#):
var hello = new { Hello = "Hello" };
var world = new { World = "World" };
var helloWorld = hello + world;
Console.WriteLine(helloWorld.ToString());
//outputs {Hello = Hello, World = World}
This certainly seems possible, since no runtime information is used. Are there static languages that have this capability?
Added:
A limited version of what I'm considering is F#'s copy-and-update record expression:
let myRecord3 = { myRecord2 with Y = 100; Z = 2 }
What you're describing is known in programming language research as record concatenation. There has been some work on static type systems for record concatenation, mostly in the context of automatic type inference a la Haskell or ML. To the best of my knowledge it has not yet made an impact on any mainstream programming languages.

Scala String format named parameters (Winner: Ugliest Code)

I came up with a trick to use named parameters in Scala. Is there a better way? What are the downsides?
<x>
|CREATE OR REPLACE FUNCTION myFunction({columns.map(column => column.name).
mkString(",\n")})
|RETURNS BOOLEAN AS $$
|BEGIN
| -- more stuff
|END;
|$$ LANGUAGE 'plpgsql';
|</x>.text.stripMargin
Watch out for ampersands in the XML body; they need to be "quoted" as & or placed in braces like {"&"}. Do I win a prize for ugliest code? :-)
I think that if you need a string formater on this scale, you need a Builder or a templating engine, like Velocity. Incidentally, I've found Scala's good for builders and DSLs.
If you don't mind a compiler plugin, try Johannes Rudolph's Scala Enhanced Strings. I like it a lot.
Good news! Scala 2.10.0 introduced real, functional string interpolation!
The docs are available here: http://docs.scala-lang.org/overviews/core/string-interpolation.html
Here's a quick sample:
In Python, I used to do things like:
print "%(from)s -> %(to)s" % {"from": foo, "to": bar}
now, in Scala 2.10.0+, we can do this!
val from = "Foo"
val to = 256
println(s"$from -> $to") // Prints: Foo -> 256
There's also some format string support as well, which is pretty awesome:
val from = 10.00 // USD
val to = 984.30 // JPY
println(f"$$$from%.2f -> $to%.2fJPY") // Prints: $10.00 -> 984.30JPY
Since the second example has some minimal type expressiveness, it also gives us some basic type checking as well!
val from = 10.00
println(f"$$$from%d") // <-- Type error! Found "Double", required "Int"!

What's the name of this programming feature?

In some dynamic languages I have seen this kind of syntax:
myValue = if (this.IsValidObject)
{
UpdateGraph();
UpdateCount();
this.Name;
}
else
{
Debug.Log (Exceptions.UninitializedObject);
3;
}
Basically being able to return the last statement in a branch as the return value for a variable, not necessarily only for method returns, but they could be achieved as well.
What's the name of this feature?
Can this also be achieved in staticly typed languages such as C#? I know C# has ternary operator, but I mean using if statements, switch statements as shown above.
It is called "conditional-branches-are-expressions" or "death to the statement/expression divide".
See Conditional If Expressions:
Many languages support if expressions, which are similar to if statements, but return a value as a result. Thus, they are true expressions (which evaluate to a value), not statements (which just perform an action).
That is, if (expr) { ... } is an expression (could possible be an expression or a statement depending upon context) in the language grammar just as ?: is an expression in languages like C, C# or Java.
This form is common in functional programming languages (which eschew side-effects) -- however, it is not "functional programming" per se and exists in other language that accept/allow a "functional like syntax" while still utilizing heavy side-effects and other paradigms (e.g. Ruby).
Some languages like Perl allow this behavior to be simulated. That is, $x = eval { if (true) { "hello world!" } else { "goodbye" } }; print $x will display "hello world!" because the eval expression evaluates to the last value evaluated inside even though the if grammar production itself is not an expression. ($x = if ... is a syntax error in Perl).
Happy coding.
To answer your other question:
Can this also be achieved in staticly typed languages such as C#?
Is it a thing the language supports? No. Can it be achieved? Kind of.
C# --like C++, Java, and all that ilk-- has expressions and statements. Statements, like if-then and switch-case, don't return values and there fore can't be used as expressions. Also, as a slight aside, your example assigns myValue to either a string or an integer, which C# can't do because it is strongly typed. You'd either have to use object myValue and then accept the casting and boxing costs, use var myValue (which is still static typed, just inferred), or some other bizarre cleverness.
Anyway, so if if-then is a statement, how do you do that in C#? You'd have to build a method to accomplish the goal of if-then-else. You could use a static method as an extension to bools, to model the Smalltalk way of doing it:
public static T IfTrue(this bool value, Action doThen, Action doElse )
{
if(value)
return doThen();
else
return doElse();
}
To use this, you'd do something like
var myVal = (6 < 7).IfTrue(() => return "Less than", () => return "Greater than");
Disclaimer: I tested none of that, so it may not quite work due to typos, but I think the principle is correct.
The new IfTrue() function checks the boolean it is attached to and executes one of two delegates passed into it. They must have the same return type, and neither accepts arguments (use closures, so it won't matter).
Now, should you do that? No, almost certainly not. Its not the proper C# way of doing things so it's confusing, and its much less efficient than using an if-then. You're trading off something like 1 IL instruction for a complex mess of classes and method calls that .NET will build behind the scenes to support that.
It is a ternary conditional.
In C you can use, for example:
printf("Debug? %s\n", debug?"yes":"no");
Edited:
A compound statement list can be evaluated as a expression in C. The last statement should be a expression and the whole compound statement surrounded by braces.
For example:
#include <stdio.h>
int main(void)
{
int a=0, b=1;
a=({
printf("testing compound statement\n");
if(b==a)
printf("equals\n");
b+1;
});
printf("a=%d\n", a);
return 0;
}
So the name of the characteristic you are doing is assigning to a (local) variable a compound statement. Now I think this helps you a little bit more. For more, please visit this source:
http://www.chemie.fu-berlin.de/chemnet/use/info/gcc/gcc_8.html
Take care,
Beco.
PS. This example makes more sense in the context of your question:
a=({
int c;
if(b==a)
c=b+1;
else
c=a-1;
c;
});
In addition to returning the value of the last expression in a branch, it's likely (depending on the language) that myValue is being assigned to an anonymous function -- or in Smalltalk / Ruby, code blocks:
A block of code (an anonymous function) can be expressed as a literal value (which is an object, since all values are objects.)
In this case, since myValue is actually pointing to a function that gets invoked only when myValue is used, the language probably implements them as closures, which are originally a feature of functional languages.
Because closures are first-class functions with free variables, closures exist in C#. However, the implicit return does not occur; in C# they're simply anonymous delegates! Consider:
Func<Object> myValue = delegate()
{
if (this.IsValidObject)
{
UpdateGraph();
UpdateCount();
return this.Name;
}
else
{
Debug.Log (Exceptions.UninitializedObject);
return 3;
}
};
This can also be done in C# using lambda expressions:
Func<Object> myValue = () =>
{
if (this.IsValidObject) { ... }
else { ... }
};
I realize your question is asking about the implicit return value, but I am trying to illustrate that there is more than just "conditional branches are expressions" going on here.
Can this also be achieved in staticly
typed languages?
Sure, the types of the involved expressions can be statically and strictly checked. There seems to be nothing dependent on dynamic typing in the "if-as-expression" approach.
For example, Haskell--a strict statically typed language with a rich system of types:
$ ghci
Prelude> let x = if True then "a" else "b" in x
"a"
(the example expression could be simpler, I just wanted to reflect the assignment from your question, but the expression to demonstrate the feature could be simlpler:
Prelude> if True then "a" else "b"
"a"
.)

Resources