Skip to content

Commit d4cf67a

Browse files
hyperpolymathclaude
andcommitted
feat(stdlib): pub-mark sweep — io/math/option/result/testing (closes #508)
PR #505 closed the pub-visibility gap in stdlib/string.affine and stdlib/collections.affine. This PR completes the sweep for the remaining 5 modules listed in #508. Mechanical rule (per #508 scope): Any `fn` immediately preceded by a `///` doc comment (allowing intervening contiguous `//` lines / attributes) is pub-intent and gets the `pub` keyword. | Module | pub before | pub after | now-private | |------------|-----------:|----------:|------------:| | io | 0 | 15 | 0 | | math | 0 | 36 | 0 | | option | 1 | 36 | 0 | | result | 0 | 24 | 0 | | testing | 0 | 26 | 0 | Total: 136 fns now reachable from consumers (was 1 of 137). Verification dune build bin/main.exe — clean dune runtest — 368/368 PASS Estate impact (verified by running main.exe check against the idaptik migration/ corpus before and after this change): before: 68 / 86 PASS, 18 FAIL (4 parse, 14 type) after: same numerically — the 14 `undefined value: \`min_float\`/\`max_float\`` failures now flip from "stdlib symbol unreachable" to "caller missing \`use math::{min_float, max_float};\`", which is the correct consumer-side closure. Companion idaptik PR adds those. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com>
1 parent 87170b5 commit d4cf67a

5 files changed

Lines changed: 136 additions & 136 deletions

File tree

stdlib/io.affine

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use string::{ split, join };
3737
///
3838
/// Example:
3939
/// printf("Hello, {}! You are {} years old.", ["Alice", 30])
40-
fn printf(format: String, args: [Any]) -> () {
40+
pub fn printf(format: String, args: [Any]) -> () {
4141
let flen = len(format);
4242
let mut arg_idx = 0;
4343
let mut i = 0;
@@ -59,23 +59,23 @@ fn printf(format: String, args: [Any]) -> () {
5959
}
6060

6161
/// Print formatted string with trailing newline
62-
fn println_fmt(format: String, args: [Any]) -> () {
62+
pub fn println_fmt(format: String, args: [Any]) -> () {
6363
printf(format, args);
6464
println("");
6565
}
6666

6767
/// Print debug representation of any value
68-
fn debug<T>(value: T) -> () {
68+
pub fn debug<T>(value: T) -> () {
6969
eprintln("DEBUG: " ++ show(value));
7070
}
7171

7272
/// Print error with newline to stderr (convenience wrapper)
73-
fn error(msg: String) -> () {
73+
pub fn error(msg: String) -> () {
7474
eprintln("[ERROR] " ++ msg);
7575
}
7676

7777
/// Print warning with newline to stderr
78-
fn warn(msg: String) -> () {
78+
pub fn warn(msg: String) -> () {
7979
eprintln("[WARN] " ++ msg);
8080
}
8181

@@ -86,7 +86,7 @@ fn warn(msg: String) -> () {
8686
// read_file, write_file, append_file, file_exists are builtins — see module header
8787

8888
/// Read file as a list of lines
89-
fn read_lines(path: String) -> Result<[String], String> {
89+
pub fn read_lines(path: String) -> Result<[String], String> {
9090
match read_file(path) {
9191
Ok(content) => Ok(split(content, "\n")),
9292
Err(msg) => Err(msg)
@@ -97,7 +97,7 @@ fn read_lines(path: String) -> Result<[String], String> {
9797
///
9898
/// Note: this reads the entire file; a more efficient builtin would be
9999
/// preferable for large files once the runtime supports stat().
100-
fn file_size(path: String) -> Result<Int, String> {
100+
pub fn file_size(path: String) -> Result<Int, String> {
101101
match read_file(path) {
102102
Ok(content) => Ok(len(content)),
103103
Err(msg) => Err(msg)
@@ -124,7 +124,7 @@ extern fn remove_dir(path: String) -> Result<(), String>;
124124
// ============================================================================
125125

126126
/// Join path components with the system separator (/)
127-
fn path_join(components: [String]) -> String {
127+
pub fn path_join(components: [String]) -> String {
128128
let mut result = "";
129129
let mut first = true;
130130
for component in components {
@@ -142,7 +142,7 @@ fn path_join(components: [String]) -> String {
142142
///
143143
/// Returns None if no extension is found.
144144
/// Example: path_extension("file.txt") => Some("txt")
145-
fn path_extension(path: String) -> Option<String> {
145+
pub fn path_extension(path: String) -> Option<String> {
146146
let plen = len(path);
147147
let mut i = plen - 1;
148148
while i >= 0 {
@@ -166,7 +166,7 @@ fn path_extension(path: String) -> Option<String> {
166166
/// Get the filename component from a path
167167
///
168168
/// Example: path_filename("/home/user/file.txt") => "file.txt"
169-
fn path_filename(path: String) -> String {
169+
pub fn path_filename(path: String) -> String {
170170
let plen = len(path);
171171
if plen == 0 {
172172
return "";
@@ -185,7 +185,7 @@ fn path_filename(path: String) -> String {
185185
/// Get the directory component from a path
186186
///
187187
/// Example: path_dirname("/home/user/file.txt") => "/home/user"
188-
fn path_dirname(path: String) -> String {
188+
pub fn path_dirname(path: String) -> String {
189189
let plen = len(path);
190190
if plen == 0 {
191191
return ".";
@@ -207,7 +207,7 @@ fn path_dirname(path: String) -> String {
207207
/// Get the filename without its extension (stem)
208208
///
209209
/// Example: path_stem("archive.tar.gz") => "archive.tar"
210-
fn path_stem(path: String) -> String {
210+
pub fn path_stem(path: String) -> String {
211211
let filename = path_filename(path);
212212
let flen = len(filename);
213213
let mut i = flen - 1;
@@ -239,7 +239,7 @@ extern fn chdir(path: String) -> Result<(), String>;
239239
// read_line is a builtin — see module header
240240

241241
/// Read all input from stdin until EOF
242-
fn read_stdin() -> Result<String, String> {
242+
pub fn read_stdin() -> Result<String, String> {
243243
let mut parts = [];
244244
let mut done = false;
245245
while !done {
@@ -256,7 +256,7 @@ fn read_stdin() -> Result<String, String> {
256256
}
257257

258258
/// Prompt user for input and return their response
259-
fn prompt(message: String) -> Result<String, String> {
259+
pub fn prompt(message: String) -> Result<String, String> {
260260
print(message);
261261
read_line()
262262
}
@@ -268,7 +268,7 @@ fn prompt(message: String) -> Result<String, String> {
268268
// time_now is a builtin — see module header
269269

270270
/// Measure the wall-clock time of a function call (in seconds)
271-
fn timed<T>(f: () -> T) -> (T, Float) {
271+
pub fn timed<T>(f: () -> T) -> (T, Float) {
272272
let start = time_now();
273273
let result = f();
274274
let elapsed = time_now() - start;

stdlib/math.affine

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,22 @@ const NEG_INFINITY: Float = -1.0 / 0.0;
4747
// ============================================================================
4848

4949
/// Absolute value of an integer
50-
fn abs(x: Int) -> Int {
50+
pub fn abs(x: Int) -> Int {
5151
if x < 0 { -x } else { x }
5252
}
5353

5454
/// Absolute value of a float
55-
fn abs_float(x: Float) -> Float {
55+
pub fn abs_float(x: Float) -> Float {
5656
if x < 0.0 { -x } else { x }
5757
}
5858

5959
/// Sign of an integer: -1, 0, or 1
60-
fn sign(x: Int) -> Int {
60+
pub fn sign(x: Int) -> Int {
6161
if x > 0 { 1 } else if x < 0 { -1 } else { 0 }
6262
}
6363

6464
/// Sign of a float: -1, 0, or 1
65-
fn sign_float(x: Float) -> Int {
65+
pub fn sign_float(x: Float) -> Int {
6666
if x > 0.0 { 1 } else if x < 0.0 { -1 } else { 0 }
6767
}
6868

@@ -71,7 +71,7 @@ fn sign_float(x: Float) -> Int {
7171
// ============================================================================
7272

7373
/// Integer exponentiation via repeated squaring
74-
fn pow(base: Int, exp: Int) -> Int {
74+
pub fn pow(base: Int, exp: Int) -> Int {
7575
if exp == 0 {
7676
return 1;
7777
}
@@ -87,12 +87,12 @@ fn pow(base: Int, exp: Int) -> Int {
8787
}
8888

8989
/// Square of an integer
90-
fn square(x: Int) -> Int {
90+
pub fn square(x: Int) -> Int {
9191
x * x
9292
}
9393

9494
/// Cube of an integer
95-
fn cube(x: Int) -> Int {
95+
pub fn cube(x: Int) -> Int {
9696
x * x * x
9797
}
9898

@@ -105,12 +105,12 @@ fn cube(x: Int) -> Int {
105105
// floor, ceil, round, trunc are builtins — see module header
106106

107107
/// Convert an integer to a float
108-
fn to_float(n: Int) -> Float {
108+
pub fn to_float(n: Int) -> Float {
109109
float(n)
110110
}
111111

112112
/// Fractional part of a float (x - trunc(x))
113-
fn fract(x: Float) -> Float {
113+
pub fn fract(x: Float) -> Float {
114114
x - to_float(trunc(x))
115115
}
116116

@@ -121,27 +121,27 @@ fn fract(x: Float) -> Float {
121121
// sin, cos, tan, asin, acos, atan, atan2 are builtins — see module header
122122

123123
/// Convert degrees to radians
124-
fn deg_to_rad(degrees: Float) -> Float {
124+
pub fn deg_to_rad(degrees: Float) -> Float {
125125
degrees * PI / 180.0
126126
}
127127

128128
/// Convert radians to degrees
129-
fn rad_to_deg(radians: Float) -> Float {
129+
pub fn rad_to_deg(radians: Float) -> Float {
130130
radians * 180.0 / PI
131131
}
132132

133133
/// Hyperbolic sine
134-
fn sinh(x: Float) -> Float {
134+
pub fn sinh(x: Float) -> Float {
135135
(exp(x) - exp(-x)) / 2.0
136136
}
137137

138138
/// Hyperbolic cosine
139-
fn cosh(x: Float) -> Float {
139+
pub fn cosh(x: Float) -> Float {
140140
(exp(x) + exp(-x)) / 2.0
141141
}
142142

143143
/// Hyperbolic tangent
144-
fn tanh(x: Float) -> Float {
144+
pub fn tanh(x: Float) -> Float {
145145
sinh(x) / cosh(x)
146146
}
147147

@@ -152,7 +152,7 @@ fn tanh(x: Float) -> Float {
152152
// exp, log, log10, log2 are builtins — see module header
153153

154154
/// Logarithm with arbitrary base
155-
fn log_base(base: Float, x: Float) -> Float {
155+
pub fn log_base(base: Float, x: Float) -> Float {
156156
log(x) / log(base)
157157
}
158158

@@ -161,27 +161,27 @@ fn log_base(base: Float, x: Float) -> Float {
161161
// ============================================================================
162162

163163
/// Minimum of two integers
164-
fn min_int(a: Int, b: Int) -> Int {
164+
pub fn min_int(a: Int, b: Int) -> Int {
165165
if a < b { a } else { b }
166166
}
167167

168168
/// Maximum of two integers
169-
fn max_int(a: Int, b: Int) -> Int {
169+
pub fn max_int(a: Int, b: Int) -> Int {
170170
if a > b { a } else { b }
171171
}
172172

173173
/// Minimum of two floats
174-
fn min_float(a: Float, b: Float) -> Float {
174+
pub fn min_float(a: Float, b: Float) -> Float {
175175
if a < b { a } else { b }
176176
}
177177

178178
/// Maximum of two floats
179-
fn max_float(a: Float, b: Float) -> Float {
179+
pub fn max_float(a: Float, b: Float) -> Float {
180180
if a > b { a } else { b }
181181
}
182182

183183
/// Clamp an integer between min_val and max_val (inclusive)
184-
fn clamp_int(value: Int, min_val: Int, max_val: Int) -> Int {
184+
pub fn clamp_int(value: Int, min_val: Int, max_val: Int) -> Int {
185185
if value < min_val {
186186
min_val
187187
} else if value > max_val {
@@ -192,7 +192,7 @@ fn clamp_int(value: Int, min_val: Int, max_val: Int) -> Int {
192192
}
193193

194194
/// Clamp a float between min_val and max_val (inclusive)
195-
fn clamp_float(value: Float, min_val: Float, max_val: Float) -> Float {
195+
pub fn clamp_float(value: Float, min_val: Float, max_val: Float) -> Float {
196196
if value < min_val {
197197
min_val
198198
} else if value > max_val {
@@ -203,7 +203,7 @@ fn clamp_float(value: Float, min_val: Float, max_val: Float) -> Float {
203203
}
204204

205205
/// Linear interpolation between a and b by factor t (0.0 to 1.0)
206-
fn lerp(a: Float, b: Float, t: Float) -> Float {
206+
pub fn lerp(a: Float, b: Float, t: Float) -> Float {
207207
a + (b - a) * t
208208
}
209209

@@ -212,7 +212,7 @@ fn lerp(a: Float, b: Float, t: Float) -> Float {
212212
// ============================================================================
213213

214214
/// Greatest common divisor via Euclid's algorithm
215-
fn gcd(a: Int, b: Int) -> Int {
215+
pub fn gcd(a: Int, b: Int) -> Int {
216216
let mut x = abs(a);
217217
let mut y = abs(b);
218218

@@ -226,25 +226,25 @@ fn gcd(a: Int, b: Int) -> Int {
226226
}
227227

228228
/// Least common multiple
229-
fn lcm(a: Int, b: Int) -> Int {
229+
pub fn lcm(a: Int, b: Int) -> Int {
230230
if a == 0 || b == 0 {
231231
return 0;
232232
}
233233
abs(a * b) / gcd(a, b)
234234
}
235235

236236
/// Check if n is even
237-
fn is_even(n: Int) -> Bool {
237+
pub fn is_even(n: Int) -> Bool {
238238
n % 2 == 0
239239
}
240240

241241
/// Check if n is odd
242-
fn is_odd(n: Int) -> Bool {
242+
pub fn is_odd(n: Int) -> Bool {
243243
n % 2 != 0
244244
}
245245

246246
/// Check if n is a prime number (trial division)
247-
fn is_prime(n: Int) -> Bool {
247+
pub fn is_prime(n: Int) -> Bool {
248248
if n < 2 {
249249
return false;
250250
}
@@ -265,7 +265,7 @@ fn is_prime(n: Int) -> Bool {
265265
}
266266

267267
/// Integer division rounding towards negative infinity (floor division)
268-
fn div_floor(a: Int, b: Int) -> Int {
268+
pub fn div_floor(a: Int, b: Int) -> Int {
269269
let q = a / b;
270270
if (a % b != 0) && ((a < 0) != (b < 0)) {
271271
q - 1
@@ -275,7 +275,7 @@ fn div_floor(a: Int, b: Int) -> Int {
275275
}
276276

277277
/// Modulo that always returns a non-negative result
278-
fn mod_positive(a: Int, b: Int) -> Int {
278+
pub fn mod_positive(a: Int, b: Int) -> Int {
279279
let r = a % b;
280280
if r < 0 {
281281
r + abs(b)
@@ -289,7 +289,7 @@ fn mod_positive(a: Int, b: Int) -> Int {
289289
// ============================================================================
290290

291291
/// Factorial of n (n!)
292-
fn factorial(n: Int) -> Int {
292+
pub fn factorial(n: Int) -> Int {
293293
if n <= 1 {
294294
1
295295
} else {
@@ -298,7 +298,7 @@ fn factorial(n: Int) -> Int {
298298
}
299299

300300
/// n-th Fibonacci number (iterative)
301-
fn fibonacci(n: Int) -> Int {
301+
pub fn fibonacci(n: Int) -> Int {
302302
if n <= 1 {
303303
n
304304
} else {
@@ -316,17 +316,17 @@ fn fibonacci(n: Int) -> Int {
316316
}
317317

318318
/// Sum of first n natural numbers: 1 + 2 + ... + n
319-
fn sum_naturals(n: Int) -> Int {
319+
pub fn sum_naturals(n: Int) -> Int {
320320
n * (n + 1) / 2
321321
}
322322

323323
/// Sum of first n squares: 1^2 + 2^2 + ... + n^2
324-
fn sum_squares(n: Int) -> Int {
324+
pub fn sum_squares(n: Int) -> Int {
325325
n * (n + 1) * (2 * n + 1) / 6
326326
}
327327

328328
/// Binomial coefficient C(n, k) = n! / (k! * (n-k)!)
329-
fn binomial(n: Int, k: Int) -> Int {
329+
pub fn binomial(n: Int, k: Int) -> Int {
330330
if k < 0 || k > n {
331331
return 0;
332332
}
@@ -346,7 +346,7 @@ fn binomial(n: Int, k: Int) -> Int {
346346
// ============================================================================
347347

348348
/// Arithmetic mean of a list of floats
349-
fn mean(values: [Float]) -> Float {
349+
pub fn mean(values: [Float]) -> Float {
350350
let n = len(values);
351351
if n == 0 {
352352
return 0.0;
@@ -359,7 +359,7 @@ fn mean(values: [Float]) -> Float {
359359
}
360360

361361
/// Sum of a list of floats
362-
fn sum_float(values: [Float]) -> Float {
362+
pub fn sum_float(values: [Float]) -> Float {
363363
let mut tot = 0.0;
364364
for v in values {
365365
tot = tot + v;

0 commit comments

Comments
 (0)