# Base.Chop API rationale

**URL:** <https://discourse.julialang.org/t/base-chop-api-rationale/96473>\
**Category:** Internals & Design\
**Created:** [March 22, 2023, 8:30pm UTC](https://discourse.julialang.org/t/base-chop-api-rationale/96473 "2023-03-22T20:30:38Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [March 22, 2023, 8:30pm UTC](https://discourse.julialang.org/t/base-chop-api-rationale/96473/1 "2023-03-22T20:30:38Z")

</div>

[`Base.chop`](https://docs.julialang.org/en/v1/base/strings/#Base.chop)

```julia
chop(s::AbstractString; head::Integer = 0, tail::Integer = 1)

```

> Remove the first `head` and the last `tail` characters from `s`. The call `chop(s)` removes the last character from `s`. If it is requested to remove more characters than `length(s)` then an empty string is returned.

I am curious about the reasoning for two choices:

- uses keyword arguments instead of positional
- defaults to `tail=1`

Especially the default `tail=1` I really am puzzled by: what is this function for?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 22, 2023, 8:43pm UTC](https://discourse.julialang.org/t/base-chop-api-rationale/96473/2 "2023-03-22T20:43:56Z")

</div>

> [@jar1](#):
>
> Especially the default `tail=1` I really am puzzled by: what is this function for?

See the discussion in [julia#17457](https://github.com/JuliaLang/julia/pull/17457) and [#17922](https://github.com/JuliaLang/julia/pull/17922): apparently this function was copied from the [Perl `chop` function](https://perldoc.perl.org/functions/chop) and originally _only_ removed one character from the end, before additional `head` and `tail` arguments were eventually added by [julia#24126](https://github.com/JuliaLang/julia/pull/24126) (later converted to keywords). Even then there was some contention about how useful this function is, and there are still discussions about improving the API ([#37397](https://github.com/JuliaLang/julia/issues/37397)).

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 22, 2023, 8:45pm UTC](https://discourse.julialang.org/t/base-chop-api-rationale/96473/3 "2023-03-22T20:45:25Z")

</div>

Ruby also has [`String#chop`](https://www.rubydoc.info/stdlib/core/1.9.2/String:chop).

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [April 9, 2023, 1:10pm UTC](https://discourse.julialang.org/t/base-chop-api-rationale/96473/4 "2023-04-09T13:10:45Z")

</div>

This was an unfortunate oversight when the head keyword was added. The default should definitely not be `tail=1` when a value is passed for `head`. We might even be able to change that in a minor release with a deprecation since it seems so bad. The way would be to deprecate passing a `head` value without also passing a `tail` value and then later changing the default.
