9
$\begingroup$

I guessed the output for

 (Sequence[#, 7]&)[3]

should be

 Sequence[3,7]

But my guess was wrong. See the screenshot:

enter image description here

And I tried to construct such function as pure-function, but failed.

A workaround (not as pure-function) is Seq[x_] := Sequence[x, 7]

enter image description here

Q1) Why does the code Sequence[#, 7]&)[3] fail ?
Q2) Is it possible to construct such function as a pure-function ?

$\endgroup$
4
  • $\begingroup$ One possible workaround for the pure function could be ReleaseHold@Hold[#, 7] &[3] $\endgroup$
    – Ben Izd
    Feb 17, 2022 at 14:23
  • 1
    $\begingroup$ The reason for this problem is because Function doesn't have SequenceHold or HoldAllComplete attribute, If you add it manually which is not a good idea (SetAttributes[Function, SequenceHold]) problem will be solved. $\endgroup$
    – Ben Izd
    Feb 17, 2022 at 14:28
  • 1
    $\begingroup$ If Sequence appears as argument in a function: f, it splices its own arguments into f. E.g. f[Sequence[a,b]] evaluates to f[a,b]. In your case: (Sequence[#,7]) is the same as Function[Sequence[#,7]] and this evaluates to: Function[#,7]. The first argument should be a variable name and # ist not. $\endgroup$ Feb 17, 2022 at 14:31
  • 6
    $\begingroup$ you can use (Sequence @@ {#, 7} &)[3]. $\endgroup$
    – kglr
    Feb 17, 2022 at 15:18

4 Answers 4

7
$\begingroup$

It fails because Sequence releases the hold when subjected to the syntax &, as & is effectively the same as Function. For example, the following two are semantically equivalent:

#^2 &
Function[#^2]

and now replace #^2 with Sequence[#, 7]:

Function[Sequence[#, 7]]

by which Sequence automatically releases the hold as it's supposed to, turning the expression into Function[#1, 7] or equivalently Function[Slot[1], 7], a syntax error for Function. A workaround that I could think of is just using Hold instead of Sequence and releasing it later when evaluating:

Hold[#, 7] &[3]
(* Hold[3, 7] *)

f[Hold[#, 7] &[3]] // ReleaseHold
(* f[3, 7] *)
$\endgroup$
7
$\begingroup$

##& is functionally equivalent to Sequence in most cases, and does the job here.

##&[#,7]&[3] -> Sequence[3, 7]

So long as the argument is not evaluated, ##&[...] will remain unexpanded, even under heads that do not have SequenceHold:

##& doesn't expand under a head with the HoldAll attribute

$\endgroup$
2
$\begingroup$

If your Sequence is intended to be used within an enclosing List, then you could use Splice.

Splice[{#, 7}] &

(*for example...*)
Splice[{#, 7}] &[3]
(*...returns Splice[{3, 7}]*)

(*...and...*)
{1, (Splice[{#, 7}] &)[8], 3}
(*...returns {1, 8, 7, 3}*)

Alternatively, you just need to delay the application of Sequence (as pointed out in the comment by kglr).

Sequence @@ {#, 7} &

(*for example...*)
Sequence @@ {#, 7} &[8]
(*...returns Sequence[8, 7]*)
$\endgroup$
2
$\begingroup$

An alternative way would be to use Construct:

(Construct[Sequence,#,7]&)[3]

(* Sequence[3, 7] *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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