You don't need mutable state for your example. For 'add bookmark', a new bookmark list can be created that has the same contents as the old list but with one new entry. This is the way most immutable programming works; rather than make changes to an existing object graph, you just create a new object graph that reflects the new state of the world. When everything is immutable, it is easy to share large portions of the object graph between 'old' and 'new' versions.
One level deeper in your example, suppose a 'browser' is an data structure object with the following information: current web page, user's homepage, and list of bookmarks. This may be represented in memory as a tree that looks something like this:
browser = {
curPage --> "http://current"
homePage --> "http://home"
favorites --> { data --> "http://firstFav"
next --> { data --> "http://secondFav"
next --> null } }
}
Now the 'AddFavorite' function would take as input such a data structure and return a new data structure like so
browser = *{
curPage --> "http://current"
homePage --> "http://home"
favorites --> *{ data --> *"http://newFav"*
next --> { data --> "http://firstFav"
next --> { data --> "http://secondFav"
next --> null } } }*
}*
The bits marked with a '*' are new objects - there's a new linked list node at the front of favorites, containing a new string, and the browser structure itself is new (it must be since it has a new 'favorites' pointer).
You can model all 'stateful' computation like this, as functions that take in a 'previous world' as input and return a 'next world' as output; this is the essence of state monads in a language like Haskell.