Group Abstract Group Abstract

Message Boards Message Boards

0
|
3.1K Views
|
3 Replies
|
2 Total Likes
View groups...
Share
Share this post:

Opinion about creating a package that has two functions in it

Posted 3 years ago

I am following the excellent book by Roman Maeder, Programming in Mathematica, and now I am trying to create my first package.

I want to write down a package that lets the end user to use the following function f1, whereas in turn f1 makes use of the function n:

f1[x_] := Range[n[x]]
n[k_] := 10 + k

That is, for f1[3], for example, you get the list

{1,2,3,4,…,13}

(because you add 10 to 3).

I would like to have the community's opinion about this Minimal Working package.

Let's put aside things related to error messages, pattern matching and/or conditions in the input of the arguments for f1 and n. For example, one doesn't really need to define the function n, simply use a pure function, but I rather want to emphasize the concept of making use of two functions in order to complete a computation.

Maeder notes the following in the beginning of §1.2 that

  • Auxiliary functions or private variables that are used inside the package would be accessible to the user. User could rely on the details of the implementation or make changes to it.
  • One can pass variables as arguments that are also used locally inside the function.

Am I missing any of these in this package?

In particular, should I use a Module in the definition of f1?

Full Code:

(* ::Package:: *)

(* :Title: My first package *)


(* :Author: Ehud Behar *)


BeginPackage["MyPackage`"]


Begin["`Private`"]


f1[x_] :=
    Range[1, n[x]]


n[k_] :=
  With[{add = 10}, (*decide by how much to lengthen the list*)
    add+k
  ]


End[]


EndPackage[]
POSTED BY: Ehud Behar
3 Replies
Posted 3 years ago

Can you provide more context around Maeder's comments? Those statements sound like they are dependent on some previous discussion. For example, "Auxiliary functions or private variables that are used inside the package would be accessible to the user" doesn't sound like something that is always true, but instead depends on how you structure your package (specifically when you expose your variables for the first time).

As it stands right now, neither of your functions are "published". That is, to use f1, you'd need to do this:

MyPackage`Private`f1[5]

I'm not really sure if this has anything to do with your question, but continuing...

To make f1 useable without using the fully-qualified name (i.e. the name with the full context), you need to make sure it's in the MyPackage context. This would be as easy as just inserting the expression f1 between BeginPackage and Begin (I mean literally just f1, not the definition, just the symbol). Typically, however, people put usage messages in that space, which, as a side effect, puts the symbol into the right context. I'm assuming that the function n has no direct utility to package users, so no need to expose it in the main package context.

Side note, there's no benefit to using With to define n, at least not with this simplistic example. Along the same lines, I see no benefit to using Module for f1 (again, for this simplistic example, at least).

POSTED BY: Eric Rimbey
Posted 3 years ago

I remembered that I actually own that book, so went to look at that section. I can't quite discern from your original question whether you were understanding his point. That list of things at the beginning of 1.2 (the stuff about auxiliary functions and collision of variable names etc) were bad things. The following examples using Module were attempts to avoid those things, but he eventually gets to the "best" way to deal with these things: contexts. It's precisely because you are defining your functions in MyPackage`Private that you don't need to worry about variable name collision, and thus why you don't need Module to protect your variables.

POSTED BY: Eric Rimbey
Posted 3 years ago

Eric Rimbey, thank you very much. I didn't understand why I needed to go all the way into writing MyPackagePrivatef1[5] in order to make use of my new function. Thanks for that piece of knowledge.

Maeder wrote at the former section a function that is built of a module a with, similar to that structure:

f1[arg1_,arg2_]:=
  Module[{arg3,arg4},
    arg3=f2[arg5];
    arg4=f2[arg6,arg5]
  ]
f2[arg3_]:=
  With[{arg3=const},
    BuiltInFunction[arg3]
  ]

And then explained that maybe it works, but you should actually put into a package with contexts and so forth.

POSTED BY: Ehud Behar
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard