2

Many programming languages permit natural manipulation of strings, and some languages permit the manipulations of lists too.

More often then not (always?), these operations are done as procedure calls, or as member functions.

Many programming languages do implement in syntax the fairly typical set {prepend, replace, append} on lists (and/or strings).

I would like to know if there as/was a programming language that has a syntax that minimises/rationalises/orthogonalises the insertion syntax of items into a list by syntax design?

Python - as a simple example - has only: https://stackoverflow.com/questions/18033339/python-insert-operation-on-list

mylist.insert(10,'5')

Note: In python list insertion is implemented as a member function.

But: Python does have some syntactic sugar for removing elements from a list: e.g.

del mylist[4:7]

I like to know of any languages actually try to integrate (or have strategy) for list insertion as part of the syntax?

An example of insertion by construction: Here is some code from a fairly typical "Brand X" language, demonstrating typical prepend/replace/append operations {or operators, vis-à-vis syntatic sugar}, notice there is no obvious syntax for {in place} inserting (or removing) from the middle of a list. {It has to be done "by construction", or by calling a procedure}

# Demonstration of prefix, replace and append operations to a string {or list} #
string s := "23XX78";
"1"    +=: s;    # Prefix a char "1" to the string "in place" #
s[4:5] := "46";  # In place replace a char at pos 2 in a string #
s      +:= "9!"; # Append a string "9!" char to the string #    
# 
  Although inserting into a list is intuitive, 
  * it is by construction (hence prone to typos/index-flips)
  * it is not "in place"
  e.g. ...
#
s:=s[:4]+"5"+s[5:];

print(s)

Output: "123456789!"

Another example for strings:

s[:4]+="5"
3
  • 5
    Lisp comes to mind... I guess – Lescai Ionel Oct 2 '13 at 6:49
  • Good idea, what a classic, I'll take a look at Lisp. But I have no idea about Lisp's actual syntax. – NevilleDNZ Oct 2 '13 at 7:00
  • Have you tried your syntax on python lists? – mouviciel Oct 2 '13 at 7:12
7

Python actually supports insertion of arbitrary sub-lists, as a part of list slice assignment. You just assign to an empty slice before the element where you want to insert a new list:

list1 = [1, 2, 3]

list1[1:1] = [10, 20, 30] # insert 3 elements at index 1
print list1 # prints [1, 10, 20, 30, 2, 3]

Many languages view lists as primarily sequential data structures, thus only allowing manipulation at their ends. This has both implementation-related and logical advantages: e.g. sequentially you can handle lists of unknown arbitrary length.

Often when you find yourself in need to insert an element into the middle of a list, it's a good sign that what's you're doing is a hack due to a poor design. (Python's sys.path[0:0] manipulation is an example.)

6
  • Actually, most of the syntax suggestions of OP work in python on lists (except "1" += s). – mouviciel Oct 2 '13 at 7:11
  • re: "+=:" ... python lists have: list1.__rmul__(), and a list1.__iadd__(), if python had: list1.__iradd__()? ... – NevilleDNZ Oct 2 '13 at 8:24
  • I checked and found inserting into a python string is to be done by construction: s:=s[:4]+"5"+s[5:]; while the construct c[4:4]="5" does not work for strings. I'm hoping that another language has good examples of string/list insertion. – NevilleDNZ Oct 3 '13 at 4:15
  • 1
    Strings are immutable (and for a good reason); c[1] = 'x' won't work either. If you find yourself wanting to modify a string, especially in the middle, usually you should really use a list of strings, and join() them in the very end. – 9000 Oct 3 '13 at 5:19
  • It occurs to me that list1[1:1] = [10, 20, 30] is a semantic error, and should generate an exception... eg ValueError: too many values to unpack. It might be worth removing this quirk from Python3 – NevilleDNZ Oct 4 '13 at 2:20
2

F# provides a :: operator that is used both for construction and destructuring:

(* this will append 1 as a head to a list containing 2 and 3 *)
let lst = 1 :: [2; 3]
> [1; 2; 3]

(* this will use pattern matching to destructure the list and return 
   the sum of first two elements; if not possible, then the first element; otherwise 0 *)
let func = function | a::b::_ -> a + b | h :: _ -> h | _ -> 0
func lst
> 3

There's also a @ operator for concatenating lists:

(* this will return a concatenated lists *)
let longer = lst @ lst
> [1; 2; 3; 1; 2; 3]

Using those two, you can insert an element in the 'middle' of the list like this:

let a, b = [1; 2], [4; 5; 6]
let c = a @ (3 :: b)
> [1; 2; 3; 4; 5]

We're talking regular singly linked lists here, however, so no indexing into the list. You have to split it by other means (function calls) if you want the element inserted at an arbitrary position.

The same applies to other ML family members: SML, OCaml, Scala and also Haskell (it uses : and ++ respectively, though).

0

Why would you actually want list insertion as part of syntax? It's a fairly uncommon operation, and I'd question the wisdom of creating special syntax for this when a regular function should work just fine.

Note that if you are using a Lisp, it's trivial to add new syntax using macros.

Here's an example in Clojure:

(defmacro insert [list at [start end] in target]
     (when-not (and (= "at" (name at)) (= "in" (name in))) 
       (throw (Error. "Syntax error: should be like (insert <values> at [3 4] in <target-list>)")) )
     `(let [target# ~target ] 
        (concat 
          (take ~start target#)
          ~list
          (drop ~end target#))))

(insert [:a :b :c] at [3 4] in [1 2 3 4 5])
=> (1 2 3 :a :b :c 5)

Note that this isn't a function: we have genuinely created new syntax (see the "at" and "in" symbols - this wouldn't work as a regular function)

I still don't recommend doing this (you should normally prefer a regular function), but the feature is there if you want it....

2
  • SQL ♥ Insert... ☺ – NevilleDNZ Oct 4 '13 at 3:24
  • Haha it's a bit of a stretch to define SQL as a "programming language". As a query DSL, maybe :-) – mikera Oct 4 '13 at 6:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.